feat: added tests for wishlist

This commit is contained in:
2025-01-02 11:29:45 +01:00
parent eed3905638
commit 7ef4d58ffa
9 changed files with 118 additions and 28 deletions
+3 -1
View File
@@ -10,7 +10,9 @@ class ProductFilter(django_filters.FilterSet):
field_name="name", lookup_expr="icontains", label=_("Nombre") field_name="name", lookup_expr="icontains", label=_("Nombre")
) )
tags = django_filters.BaseInFilter(field_name="tags", label=_("Etiquetas")) 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_lt = django_filters.NumberFilter(method="filter_price_lt")
price_gt = django_filters.NumberFilter(method="filter_price_gt") price_gt = django_filters.NumberFilter(method="filter_price_gt")
o = OrderingFilter( o = OrderingFilter(
+3 -2
View File
@@ -1,9 +1,10 @@
# Generated by Django 5.1.3 on 2024-12-31 09:48 # 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.db.models.deletion
import django.utils.timezone import django.utils.timezone
import uuid
from decimal import Decimal
from django.conf import settings from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
+29 -10
View File
@@ -37,11 +37,26 @@ class Tag(models.Model):
class ProductCategory(models.Model): class ProductCategory(models.Model):
name = models.CharField(max_length=32) 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')) parent = models.ForeignKey(
promoted = models.BooleanField(default=False, verbose_name=_('promocionada')) "shop.ProductCategory",
hidden = models.BooleanField(default=False, verbose_name=_('oculta')) on_delete=models.SET_NULL,
show_in_navbar = models.BooleanField(default=False, verbose_name=_('mostrar en cabecera')) null=True,
slug = models.SlugField(max_length=48, blank=True, default="", verbose_name=_("slug"), unique=True, db_index=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): def __str__(self):
return self.name return self.name
@@ -89,7 +104,9 @@ class Product(TimestampedModel):
"files.FileUpload", blank=True, verbose_name=_("imágenes") "files.FileUpload", blank=True, verbose_name=_("imágenes")
) )
tags = models.ManyToManyField("shop.Tag", blank=True, verbose_name=_("etiquetas")) 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( brand = models.ForeignKey(
"shop.Brand", "shop.Brand",
blank=True, blank=True,
@@ -504,9 +521,11 @@ class ShippingMethod(models.Model):
class WishlistedProduct(TimestampedModel): class WishlistedProduct(TimestampedModel):
user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name=_('usuario')) user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name=_("usuario"))
product = models.ForeignKey('shop.Product', on_delete=models.CASCADE, verbose_name=_('producto')) product = models.ForeignKey(
"shop.Product", on_delete=models.CASCADE, verbose_name=_("producto")
)
class Meta: class Meta:
verbose_name = _('productos deseados') verbose_name = _("productos deseados")
verbose_name_plural = _('productos deseados') verbose_name_plural = _("productos deseados")
+3 -1
View File
@@ -4,7 +4,9 @@ from web.models import WebSettings
def web_settings(request): def web_settings(request):
settings = WebSettings.load() 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 { return {
"logo": settings.logo.url if settings.logo else "", "logo": settings.logo.url if settings.logo else "",
+3 -1
View File
@@ -13,5 +13,7 @@ class TestCategoryView(TestCase, CreateProductsMixin):
category = ProductCategory.objects.create( category = ProductCategory.objects.create(
name="category 1", show_in_navbar=True, hidden=False 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 assert response.status_code == 200
+56
View File
@@ -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()
+11 -7
View File
@@ -6,12 +6,12 @@ from web.views.web import (
add_cart_item, add_cart_item,
add_to_wishlist, add_to_wishlist,
cart_detail, cart_detail,
category_view,
delete_cart_item, delete_cart_item,
delete_from_wishlist, delete_from_wishlist,
index, index,
manifest, manifest,
product_detail, product_detail,
category_view,
) )
app_name = "web" app_name = "web"
@@ -21,26 +21,30 @@ urlpatterns = [
path("categories/<str:slug>/", category_view, name="category_view"), path("categories/<str:slug>/", category_view, name="category_view"),
path("products/<int:pk>/<str:slug>/", product_detail, name="product_detail"), path("products/<int:pk>/<str:slug>/", product_detail, name="product_detail"),
path("cart/", cart_detail, name="cart_detail"), path("cart/", cart_detail, name="cart_detail"),
# users # users
path("login/", login, name="login"), path("login/", login, name="login"),
path("logout/", logout, name="logout"), path("logout/", logout, name="logout"),
path("register/", register, name="register"), path("register/", register, name="register"),
path("reset-password/", reset_password, name="reset-password"), path("reset-password/", reset_password, name="reset-password"),
path("my-account/", my_account, name="my_account"), path("my-account/", my_account, name="my_account"),
# components # components
path("web/components/products/", list_products, name="list_products"), path("web/components/products/", list_products, name="list_products"),
path("web/components/cart-dropdown/", cart_dropdown, name="cart_dropdown"), path("web/components/cart-dropdown/", cart_dropdown, name="cart_dropdown"),
path("web/components/cart/", cart, name="cart"), path("web/components/cart/", cart, name="cart"),
path("web/components/wishlist-button/<int:pk>/", wishlist_button, name="wishlist_button"), path(
"web/components/wishlist-button/<int:pk>/",
wishlist_button,
name="wishlist_button",
),
# api # api
path("web/add-cart-item/", add_cart_item, name="add_cart_item"), path("web/add-cart-item/", add_cart_item, name="add_cart_item"),
path("web/delete-cart-item/<int:pk>/", delete_cart_item, name="delete_cart_item"), path("web/delete-cart-item/<int:pk>/", delete_cart_item, name="delete_cart_item"),
path("web/add-to-wishlist/", add_to_wishlist, name="add_to_wishlist"), path("web/add-to-wishlist/", add_to_wishlist, name="add_to_wishlist"),
path("web/delete-from-wishlist/<int:pk>/", delete_from_wishlist, name="delete_from_wishlist"), path(
"web/delete-from-wishlist/<int:pk>/",
delete_from_wishlist,
name="delete_from_wishlist",
),
# manifest # manifest
path("manifest.json", manifest, name="manifest_json"), path("manifest.json", manifest, name="manifest_json"),
] ]
+6 -4
View File
@@ -1,6 +1,6 @@
from decimal import Decimal 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 django.views.generic import TemplateView
from shop.filters import ProductFilter from shop.filters import ProductFilter
@@ -76,11 +76,13 @@ def cart(request, *args, **kwargs):
class WishlistButton(TemplateView): class WishlistButton(TemplateView):
template_name = 'components/products/wishlist_button.html' template_name = "components/products/wishlist_button.html"
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
product = get_object_or_404(Product, pk=self.kwargs.get('pk')) product = get_object_or_404(Product, pk=self.kwargs.get("pk"))
is_wishlisted = WishlistedProduct.objects.filter(user=self.request.user, product=product).exists() is_wishlisted = WishlistedProduct.objects.filter(
user=self.request.user, product=product
).exists()
return { return {
"is_wishlisted": is_wishlisted, "is_wishlisted": is_wishlisted,
+4 -2
View File
@@ -27,7 +27,7 @@ class CategoryView(TemplateView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
settings = WebSettings.load() settings = WebSettings.load()
slug = kwargs.get('slug') slug = kwargs.get("slug")
category = ProductCategory.objects.get(slug=slug) category = ProductCategory.objects.get(slug=slug)
return { return {
@@ -140,7 +140,9 @@ def add_to_wishlist(request, *args, **kwargs):
] ]
) )
def delete_from_wishlist(request, pk, *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() wishlisted_item.delete()
return HttpResponse(status=204, headers={"HX-Trigger": "updated-wishlist"}) return HttpResponse(status=204, headers={"HX-Trigger": "updated-wishlist"})