feat: add favorites feature for users
All checks were successful
Build and Push Docker Image / build (push) Successful in 51s
All checks were successful
Build and Push Docker Image / build (push) Successful in 51s
- Implemented `Favorite` model with unique user-item constraint and timestamped records - Added `favorites:index` and `favorites:toggle` views with AJAX support for toggling favorites - Built templates and front-end assets for the favorites page and integration with item grids - Extended header with favorites link and dynamic counter - Added tests covering models, views, and templates for the favorites functionality - Updated admin to enable management of favorites via Django admin interface
This commit is contained in:
@@ -2,6 +2,7 @@ from django.test import TestCase, override_settings
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.core.exceptions import ValidationError
|
||||
|
||||
from favorites.models import Favorite
|
||||
from items.models import Category, Item, ItemImage, Subcategory
|
||||
|
||||
|
||||
@@ -52,7 +53,7 @@ class CatalogViewTests(TestCase):
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertContains(response, "Мойки")
|
||||
self.assertContains(response, "Смесители")
|
||||
self.assertNotContains(response, "Подсветка")
|
||||
self.assertNotContains(response, 'href="/catalog/decor/?subcategory=lights"')
|
||||
|
||||
def test_subcategory_page_shows_only_selected_subcategory_items(self):
|
||||
Item.objects.create(
|
||||
@@ -141,6 +142,36 @@ class CatalogViewTests(TestCase):
|
||||
|
||||
self.assertContains(response, 'href="/catalog/plumbing/kitchen-sink/"')
|
||||
|
||||
def test_catalog_item_card_shows_favorite_button_for_authenticated_user(self):
|
||||
user = get_user_model().objects.create_user(
|
||||
username="ann",
|
||||
email="ann@example.com",
|
||||
password="StrongPassword123",
|
||||
is_active=True,
|
||||
)
|
||||
self.client.force_login(user)
|
||||
|
||||
response = self.client.get("/catalog/")
|
||||
|
||||
self.assertContains(response, 'action="/favorites/toggle/"', html=False)
|
||||
self.assertContains(response, "Добавить в избранное")
|
||||
self.assertContains(response, 'name="item_id" value="', html=False)
|
||||
|
||||
def test_catalog_item_card_marks_favorited_item(self):
|
||||
user = get_user_model().objects.create_user(
|
||||
username="ann2",
|
||||
email="ann2@example.com",
|
||||
password="StrongPassword123",
|
||||
is_active=True,
|
||||
)
|
||||
self.client.force_login(user)
|
||||
Favorite.objects.create(user=user, item=self.sink)
|
||||
|
||||
response = self.client.get("/catalog/")
|
||||
|
||||
self.assertContains(response, "Удалить из избранного")
|
||||
self.assertContains(response, "is-active")
|
||||
|
||||
def test_detail_page_shows_item_data(self):
|
||||
ItemImage.objects.create(
|
||||
item=self.sink,
|
||||
|
||||
@@ -3,6 +3,7 @@ from dataclasses import dataclass
|
||||
from django.http import HttpRequest, HttpResponse, Http404
|
||||
from django.shortcuts import render
|
||||
|
||||
from favorites.services import get_user_favorite_item_ids
|
||||
from items.models import Category, Item, Subcategory
|
||||
|
||||
|
||||
@@ -56,6 +57,7 @@ def index(request: HttpRequest, category: str | None = None) -> HttpResponse:
|
||||
'items': items,
|
||||
'selected_category': selected_category,
|
||||
'selected_subcategory': selected_subcategory,
|
||||
'favorite_item_ids': get_user_favorite_item_ids(request.user),
|
||||
})
|
||||
|
||||
|
||||
@@ -76,4 +78,5 @@ def detail(request: HttpRequest, category: str, slug: str) -> HttpResponse:
|
||||
'item': item,
|
||||
'images': images,
|
||||
'primary_image': images[0] if images else None,
|
||||
'favorite_item_ids': get_user_favorite_item_ids(request.user),
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user