All checks were successful
Build and Push Docker Image / build (push) Successful in 42s
- Added `Cart` and `CartItem` models with migrations for managing user-specific carts and items - Developed services for cart-related operations: adding, removing, and updating cart items - Built specialized templates (`cart.html`) and styled them with new CSS assets (`cart.css`) - Enabled real-time UI updates via AJAX in shopping cart interactions (`cart.js`) - Modified header to dynamically display cart link with user authentication awareness - Added Leaflet-based interactive map to the contacts page and integrated CSS/JS dependencies - Expanded tests for cart functionality, item detail page cart integration, and contacts page maps
111 lines
4.4 KiB
Python
111 lines
4.4 KiB
Python
from django.contrib.auth import get_user_model
|
||
from django.db import IntegrityError
|
||
from django.test import TestCase, override_settings
|
||
from django.urls import reverse
|
||
|
||
from items.models import Category, Item, ItemImage, Subcategory
|
||
from orders.models import Cart, CartItem
|
||
|
||
|
||
User = get_user_model()
|
||
|
||
|
||
@override_settings(MEDIA_URL="/media/")
|
||
class CartFlowTests(TestCase):
|
||
def setUp(self):
|
||
self.user = User.objects.create_user(
|
||
username="cart-user",
|
||
email="cart@example.com",
|
||
password="StrongPassword123",
|
||
is_active=True,
|
||
)
|
||
self.category = Category.objects.create(name="Сантехника", slug="plumbing")
|
||
self.subcategory = Subcategory.objects.create(name="Мойки", slug="sinks", category=self.category)
|
||
self.item = Item.objects.create(
|
||
name="Кухонная мойка",
|
||
slug="kitchen-sink",
|
||
category=self.category,
|
||
subcategory=self.subcategory,
|
||
description="Искусственный камень",
|
||
price="1600.00",
|
||
is_available=True,
|
||
)
|
||
self.unavailable_item = Item.objects.create(
|
||
name="Смеситель",
|
||
slug="tap",
|
||
category=self.category,
|
||
subcategory=self.subcategory,
|
||
description="Недоступный товар",
|
||
price="400.00",
|
||
is_available=False,
|
||
)
|
||
|
||
def test_cart_item_is_unique_per_cart(self):
|
||
cart = Cart.objects.create(user=self.user)
|
||
CartItem.objects.create(cart=cart, item=self.item, quantity=1)
|
||
|
||
with self.assertRaises(IntegrityError):
|
||
CartItem.objects.create(cart=cart, item=self.item, quantity=2)
|
||
|
||
def test_add_remove_and_update_quantity_for_authenticated_user(self):
|
||
self.client.force_login(self.user)
|
||
|
||
add_response = self.client.post(
|
||
reverse("orders:add"),
|
||
data={"item_id": self.item.id, "next": reverse("orders:cart")},
|
||
)
|
||
self.assertRedirects(add_response, reverse("orders:cart"))
|
||
self.assertTrue(CartItem.objects.filter(cart__user=self.user, item=self.item, quantity=1).exists())
|
||
|
||
update_response = self.client.post(
|
||
reverse("orders:update_quantity"),
|
||
data={"item_id": self.item.id, "quantity": 3, "next": reverse("orders:cart")},
|
||
)
|
||
self.assertRedirects(update_response, reverse("orders:cart"))
|
||
self.assertTrue(CartItem.objects.filter(cart__user=self.user, item=self.item, quantity=3).exists())
|
||
|
||
remove_response = self.client.post(
|
||
reverse("orders:remove"),
|
||
data={"item_id": self.item.id, "next": reverse("orders:cart")},
|
||
)
|
||
self.assertRedirects(remove_response, reverse("orders:cart"))
|
||
self.assertFalse(CartItem.objects.filter(cart__user=self.user, item=self.item).exists())
|
||
|
||
def test_add_endpoint_rejects_unavailable_item(self):
|
||
self.client.force_login(self.user)
|
||
|
||
response = self.client.post(
|
||
reverse("orders:add"),
|
||
data={"item_id": self.unavailable_item.id, "next": reverse("orders:cart")},
|
||
follow=True,
|
||
)
|
||
|
||
self.assertEqual(response.status_code, 200)
|
||
self.assertFalse(CartItem.objects.filter(cart__user=self.user, item=self.unavailable_item).exists())
|
||
self.assertContains(response, "Недоступный товар нельзя добавить в корзину.")
|
||
|
||
def test_cart_page_shows_authenticated_user_items(self):
|
||
cart = Cart.objects.create(user=self.user)
|
||
CartItem.objects.create(cart=cart, item=self.item, quantity=2)
|
||
ItemImage.objects.create(
|
||
item=self.item,
|
||
image="items/cart-item.jpg",
|
||
alt="Фото мойки",
|
||
is_primary=True,
|
||
)
|
||
self.client.force_login(self.user)
|
||
|
||
response = self.client.get(reverse("orders:cart"))
|
||
|
||
self.assertEqual(response.status_code, 200)
|
||
self.assertContains(response, "Кухонная мойка")
|
||
self.assertContains(response, "1600,00 руб.")
|
||
self.assertContains(response, "3200,00 руб.")
|
||
self.assertContains(response, "/media/items/cart-item.jpg")
|
||
|
||
def test_cart_page_redirects_guest_to_login(self):
|
||
response = self.client.get(reverse("orders:cart"))
|
||
|
||
self.assertEqual(response.status_code, 302)
|
||
self.assertIn(reverse("users:login"), response["Location"])
|