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"])