From 7ef4d58ffa030ceba63b4f5f62100722293bc751 Mon Sep 17 00:00:00 2001 From: Pablo Moreno Date: Thu, 2 Jan 2025 11:29:45 +0100 Subject: [PATCH] feat: added tests for wishlist --- shop/filters.py | 4 ++- shop/migrations/0001_initial.py | 5 +-- shop/models.py | 39 +++++++++++++++++------ web/context_processors.py | 4 ++- web/tests/test_category_view.py | 4 ++- web/tests/test_wishlist.py | 56 +++++++++++++++++++++++++++++++++ web/urls.py | 18 ++++++----- web/views/components.py | 10 +++--- web/views/web.py | 6 ++-- 9 files changed, 118 insertions(+), 28 deletions(-) create mode 100644 web/tests/test_wishlist.py diff --git a/shop/filters.py b/shop/filters.py index ce5973b..4131f6b 100644 --- a/shop/filters.py +++ b/shop/filters.py @@ -10,7 +10,9 @@ class ProductFilter(django_filters.FilterSet): field_name="name", lookup_expr="icontains", label=_("Nombre") ) tags = django_filters.BaseInFilter(field_name="tags", label=_("Etiquetas")) - category = django_filters.BaseInFilter(field_name="categories", label=_("Categorías")) + category = django_filters.BaseInFilter( + field_name="categories", label=_("Categorías") + ) price_lt = django_filters.NumberFilter(method="filter_price_lt") price_gt = django_filters.NumberFilter(method="filter_price_gt") o = OrderingFilter( diff --git a/shop/migrations/0001_initial.py b/shop/migrations/0001_initial.py index daa8039..aa3e8c2 100644 --- a/shop/migrations/0001_initial.py +++ b/shop/migrations/0001_initial.py @@ -1,9 +1,10 @@ # Generated by Django 5.1.3 on 2024-12-31 09:48 +import uuid +from decimal import Decimal + import django.db.models.deletion import django.utils.timezone -import uuid -from decimal import Decimal from django.conf import settings from django.db import migrations, models diff --git a/shop/models.py b/shop/models.py index 857012e..1eda9c0 100644 --- a/shop/models.py +++ b/shop/models.py @@ -37,11 +37,26 @@ class Tag(models.Model): class ProductCategory(models.Model): name = models.CharField(max_length=32) - parent = models.ForeignKey('shop.ProductCategory', on_delete=models.SET_NULL, null=True, blank=True, verbose_name=_('categoría padre')) - promoted = models.BooleanField(default=False, verbose_name=_('promocionada')) - hidden = models.BooleanField(default=False, verbose_name=_('oculta')) - show_in_navbar = models.BooleanField(default=False, verbose_name=_('mostrar en cabecera')) - slug = models.SlugField(max_length=48, blank=True, default="", verbose_name=_("slug"), unique=True, db_index=True) + parent = models.ForeignKey( + "shop.ProductCategory", + on_delete=models.SET_NULL, + null=True, + blank=True, + verbose_name=_("categoría padre"), + ) + promoted = models.BooleanField(default=False, verbose_name=_("promocionada")) + hidden = models.BooleanField(default=False, verbose_name=_("oculta")) + show_in_navbar = models.BooleanField( + default=False, verbose_name=_("mostrar en cabecera") + ) + slug = models.SlugField( + max_length=48, + blank=True, + default="", + verbose_name=_("slug"), + unique=True, + db_index=True, + ) def __str__(self): return self.name @@ -89,7 +104,9 @@ class Product(TimestampedModel): "files.FileUpload", blank=True, verbose_name=_("imágenes") ) tags = models.ManyToManyField("shop.Tag", blank=True, verbose_name=_("etiquetas")) - categories = models.ManyToManyField("shop.ProductCategory", blank=True, verbose_name=_("categorías")) + categories = models.ManyToManyField( + "shop.ProductCategory", blank=True, verbose_name=_("categorías") + ) brand = models.ForeignKey( "shop.Brand", blank=True, @@ -504,9 +521,11 @@ class ShippingMethod(models.Model): class WishlistedProduct(TimestampedModel): - user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name=_('usuario')) - product = models.ForeignKey('shop.Product', on_delete=models.CASCADE, verbose_name=_('producto')) + user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name=_("usuario")) + product = models.ForeignKey( + "shop.Product", on_delete=models.CASCADE, verbose_name=_("producto") + ) class Meta: - verbose_name = _('productos deseados') - verbose_name_plural = _('productos deseados') + verbose_name = _("productos deseados") + verbose_name_plural = _("productos deseados") diff --git a/web/context_processors.py b/web/context_processors.py index 20ba856..3334d14 100644 --- a/web/context_processors.py +++ b/web/context_processors.py @@ -4,7 +4,9 @@ from web.models import WebSettings def web_settings(request): settings = WebSettings.load() - navbar_categories = ProductCategory.objects.filter(hidden=False, show_in_navbar=True) + navbar_categories = ProductCategory.objects.filter( + hidden=False, show_in_navbar=True + ) return { "logo": settings.logo.url if settings.logo else "", diff --git a/web/tests/test_category_view.py b/web/tests/test_category_view.py index ac86c06..6bd66f7 100644 --- a/web/tests/test_category_view.py +++ b/web/tests/test_category_view.py @@ -13,5 +13,7 @@ class TestCategoryView(TestCase, CreateProductsMixin): category = ProductCategory.objects.create( name="category 1", show_in_navbar=True, hidden=False ) - response = self.client.get(reverse("web:category_view", kwargs={"slug": category.slug})) + response = self.client.get( + reverse("web:category_view", kwargs={"slug": category.slug}) + ) assert response.status_code == 200 diff --git a/web/tests/test_wishlist.py b/web/tests/test_wishlist.py new file mode 100644 index 0000000..cce278d --- /dev/null +++ b/web/tests/test_wishlist.py @@ -0,0 +1,56 @@ +from django.contrib.auth.models import User +from django.test import TestCase +from django.urls import reverse + +from shop.models import Cart, CartItem, WishlistedProduct +from shop.tests.mixins import CreateProductsMixin +from web.settings import ANONYMOUS_CART_ID_COOKIE_NAME + + +class TestWishlist(TestCase, CreateProductsMixin): + def setUp(self): + self.product = self.create_product() + self.user = User.objects.create_user("vader", "darth@vader.com", "ihatesand") + + def test_logged_user_wishlist_button_for_non_wishlisted_product(self): + assert WishlistedProduct.objects.count() == 0 + self.client.force_login(self.user) + response = self.client.get( + reverse("web:wishlist_button", kwargs={"pk": self.product.pk}) + ) + assert response.status_code == 200 + + def test_logged_user_wishlist_button_for_wishlisted_product(self): + WishlistedProduct.objects.create( + user=self.user, + product=self.product, + ) + self.client.force_login(self.user) + response = self.client.get( + reverse("web:wishlist_button", kwargs={"pk": self.product.pk}) + ) + assert response.status_code == 200 + + def test_logged_user_create_wishlisted_product(self): + assert WishlistedProduct.objects.count() == 0 + self.client.force_login(self.user) + response = self.client.post( + reverse("web:add_to_wishlist"), + { + "product": self.product.pk, + } + ) + assert response.status_code == 201 + assert WishlistedProduct.objects.filter(user=self.user, product=self.product).exists() + + def test_logged_user_delete_wishlisted_product(self): + wishlisted = WishlistedProduct.objects.create( + user=self.user, + product=self.product, + ) + self.client.force_login(self.user) + response = self.client.post( + reverse("web:delete_from_wishlist", kwargs={"pk": wishlisted.pk}) + ) + assert response.status_code == 204 + assert not WishlistedProduct.objects.filter(user=self.user, product=self.product).exists() diff --git a/web/urls.py b/web/urls.py index 71ba9a5..db367a8 100644 --- a/web/urls.py +++ b/web/urls.py @@ -6,12 +6,12 @@ from web.views.web import ( add_cart_item, add_to_wishlist, cart_detail, + category_view, delete_cart_item, delete_from_wishlist, index, manifest, product_detail, - category_view, ) app_name = "web" @@ -21,26 +21,30 @@ urlpatterns = [ path("categories//", category_view, name="category_view"), path("products///", product_detail, name="product_detail"), path("cart/", cart_detail, name="cart_detail"), - # users path("login/", login, name="login"), path("logout/", logout, name="logout"), path("register/", register, name="register"), path("reset-password/", reset_password, name="reset-password"), path("my-account/", my_account, name="my_account"), - # components path("web/components/products/", list_products, name="list_products"), path("web/components/cart-dropdown/", cart_dropdown, name="cart_dropdown"), path("web/components/cart/", cart, name="cart"), - path("web/components/wishlist-button//", wishlist_button, name="wishlist_button"), - + path( + "web/components/wishlist-button//", + wishlist_button, + name="wishlist_button", + ), # api path("web/add-cart-item/", add_cart_item, name="add_cart_item"), path("web/delete-cart-item//", delete_cart_item, name="delete_cart_item"), path("web/add-to-wishlist/", add_to_wishlist, name="add_to_wishlist"), - path("web/delete-from-wishlist//", delete_from_wishlist, name="delete_from_wishlist"), - + path( + "web/delete-from-wishlist//", + delete_from_wishlist, + name="delete_from_wishlist", + ), # manifest path("manifest.json", manifest, name="manifest_json"), ] diff --git a/web/views/components.py b/web/views/components.py index 271d779..2215614 100644 --- a/web/views/components.py +++ b/web/views/components.py @@ -1,6 +1,6 @@ from decimal import Decimal -from django.shortcuts import render, get_object_or_404 +from django.shortcuts import get_object_or_404, render from django.views.generic import TemplateView from shop.filters import ProductFilter @@ -76,11 +76,13 @@ def cart(request, *args, **kwargs): class WishlistButton(TemplateView): - template_name = 'components/products/wishlist_button.html' + template_name = "components/products/wishlist_button.html" def get_context_data(self, **kwargs): - product = get_object_or_404(Product, pk=self.kwargs.get('pk')) - is_wishlisted = WishlistedProduct.objects.filter(user=self.request.user, product=product).exists() + product = get_object_or_404(Product, pk=self.kwargs.get("pk")) + is_wishlisted = WishlistedProduct.objects.filter( + user=self.request.user, product=product + ).exists() return { "is_wishlisted": is_wishlisted, diff --git a/web/views/web.py b/web/views/web.py index c9e20e4..d99a5e9 100644 --- a/web/views/web.py +++ b/web/views/web.py @@ -27,7 +27,7 @@ class CategoryView(TemplateView): def get_context_data(self, **kwargs): settings = WebSettings.load() - slug = kwargs.get('slug') + slug = kwargs.get("slug") category = ProductCategory.objects.get(slug=slug) return { @@ -140,7 +140,9 @@ def add_to_wishlist(request, *args, **kwargs): ] ) def delete_from_wishlist(request, pk, *args, **kwargs): - wishlisted_item = get_object_or_404(WishlistedProduct, product_id=pk, user=request.user) + wishlisted_item = get_object_or_404( + WishlistedProduct, product_id=pk, user=request.user + ) wishlisted_item.delete() return HttpResponse(status=204, headers={"HX-Trigger": "updated-wishlist"})