Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 115 additions & 19 deletions essenza/order/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
User = get_user_model()


# ============================================================
# TESTS: LISTADO DE PEDIDOS DEL USUARIO
# ============================================================

class OrderListUserViewTests(TestCase):
@classmethod
def setUpTestData(cls):
Expand Down Expand Up @@ -36,31 +40,31 @@ def setUpTestData(cls):
is_active=True,
)

# Pedido visible (NO en preparación) del usuario
cls.order_user = Order.objects.create(
# Pedido 1 del usuario
cls.order1 = Order.objects.create(
user=cls.user,
status=Status.ENVIADO,
status=Status.EN_PREPARACION,
address="Calle 1",
)
OrderProduct.objects.create(
order=cls.order_user,
order=cls.order1,
product=cls.product,
quantity=2
)

# Pedido del usuario que NO debe salir (EN_PREPARACION)
cls.order_hidden = Order.objects.create(
# Pedido 2 del usuario
cls.order2 = Order.objects.create(
user=cls.user,
status=Status.EN_PREPARACION,
address="Calle Oculta",
status=Status.ENVIADO,
address="Calle 2",
)
OrderProduct.objects.create(
order=cls.order_hidden,
order=cls.order2,
product=cls.product,
quantity=1
)

# Pedido de otro usuario
# Pedido de otro usuario (NO debe salir)
cls.order_other = Order.objects.create(
user=cls.other_user,
status=Status.ENVIADO,
Expand All @@ -76,22 +80,32 @@ def setUpTestData(cls):

def test_user_must_login(self):
resp = self.client.get(self.url)
self.assertEqual(resp.status_code, 302) # redirect a login
self.assertEqual(resp.status_code, 302)

def test_user_sees_only_his_non_preparacion_orders(self):
def test_user_sees_only_his_orders(self):
"""Debe ver TODOS sus pedidos, incluyendo EN_PREPARACION."""
self.client.login(email="user@test.com", password="1234")
resp = self.client.get(self.url)

self.assertEqual(resp.status_code, 200)
self.assertTemplateUsed(resp, "order/order_list_user.html")

orders = resp.context["orders"]
self.assertEqual(orders.count(), 1)
self.assertEqual(orders.first().id, self.order_user.id)
self.assertEqual(orders.count(), 2) # 🔥 YA NO FILTRAMOS NADA

# Los IDs deben coincidir
returned_ids = set(o.id for o in orders)
expected_ids = {self.order1.id, self.order2.id}
self.assertEqual(returned_ids, expected_ids)

self.assertContains(resp, "Producto A")
self.assertContains(resp, "Calle 1")
self.assertContains(resp, "Calle 2")



# ============================================================
# TESTS: LISTADO DE PEDIDOS DEL ADMIN
# ============================================================

class OrderListAdminViewTests(TestCase):
@classmethod
Expand Down Expand Up @@ -150,6 +164,11 @@ def test_admin_can_view_orders(self):
self.assertContains(resp, "user3@test.com")



# ============================================================
# TESTS: SEGUIMIENTO DE PEDIDO
# ============================================================

class OrderTrackViewTests(TestCase):
@classmethod
def setUpTestData(cls):
Expand Down Expand Up @@ -183,24 +202,101 @@ def setUpTestData(cls):
quantity=1
)

cls.url = reverse("order_track") # ⬅️ SIN args
cls.url = reverse("order_track")

def test_track_get_returns_form(self):
resp = self.client.get(self.url)
self.assertEqual(resp.status_code, 200)
self.assertTemplateUsed(resp, "order/order_track.html")

def test_track_post_valid_shows_order(self):
def test_track_post_valid_redirects_to_detail(self):
data = {"order_id": str(self.order.id), "email": "track@test.com"}
resp = self.client.post(self.url, data)
resp = self.client.post(self.url, data, follow=True)

self.assertEqual(resp.status_code, 200)
self.assertTemplateUsed(resp, "order/order_detail.html")
self.assertContains(resp, "Direccion de prueba")
self.assertContains(resp, self.order.get_status_display())

def test_track_post_invalid_shows_error(self):
data = {"order_id": "9999", "email": "track@test.com"}
resp = self.client.post(self.url, data)

self.assertEqual(resp.status_code, 200)
self.assertContains(resp, "No se ha encontrado ningún pedido")



# ============================================================
# TESTS: DETALLE DE PEDIDO
# ============================================================

class OrderDetailViewTests(TestCase):
@classmethod
def setUpTestData(cls):
cls.client = Client()

cls.user = User.objects.create_user(
username="user_detail",
email="user_detail@test.com",
password="1234",
role="user"
)
cls.other_user = User.objects.create_user(
username="other_detail",
email="other_detail@test.com",
password="1234",
role="user"
)
cls.admin = User.objects.create_user(
username="admin_detail",
email="admin_detail@test.com",
password="1234",
role="admin",
is_staff=True
)

cls.product = Product.objects.create(
name="Prod Detalle",
brand="Brand",
description="d",
category=Category.MAQUILLAJE,
price="7.00",
stock=10,
is_active=True,
)

cls.order = Order.objects.create(
user=cls.user,
status=Status.ENVIADO,
address="Calle detalle",
)
OrderProduct.objects.create(
order=cls.order,
product=cls.product,
quantity=2
)

cls.url = reverse("order_detail", args=[cls.order.id])

def test_user_must_login(self):
resp = self.client.get(self.url)
self.assertEqual(resp.status_code, 302)

def test_owner_can_view_detail(self):
self.client.login(email="user_detail@test.com", password="1234")
resp = self.client.get(self.url)

self.assertEqual(resp.status_code, 200)
self.assertTemplateUsed(resp, "order/order_detail.html")
self.assertContains(resp, "Prod Detalle")

def test_other_user_cannot_view_detail(self):
self.client.login(email="other_detail@test.com", password="1234")
resp = self.client.get(self.url)
self.assertEqual(resp.status_code, 403)

def test_admin_can_view_any_detail(self):
self.client.login(email="admin_detail@test.com", password="1234")
resp = self.client.get(self.url)
self.assertEqual(resp.status_code, 200)
self.assertTemplateUsed(resp, "order/order_detail.html")
4 changes: 3 additions & 1 deletion essenza/order/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@
from .views import (
OrderListAdminView,
OrderListUserView,
OrderTrackView
OrderTrackView,
OrderDetailView,
)

urlpatterns = [
path("admin/listado/", OrderListAdminView.as_view(), name="order_list_admin"),
path("mis-pedidos/", OrderListUserView.as_view(), name="order_list_user"),
path("seguimiento/", OrderTrackView.as_view(), name="order_track"),
path("pedido/<int:pk>/", OrderDetailView.as_view(), name="order_detail"),

]

87 changes: 65 additions & 22 deletions essenza/order/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
from django.shortcuts import render, redirect
from django.db.models import Prefetch
from .models import Order, OrderProduct, Status
from django.core.exceptions import PermissionDenied
from django.http import Http404
from django.urls import reverse



# =======================================================
# LISTADO DE PEDIDOS - ADMIN
Expand Down Expand Up @@ -38,7 +43,6 @@ class OrderListUserView(LoginRequiredMixin, View):
def get(self, request):
orders = (
Order.objects.filter(user=request.user)
.exclude(status=Status.EN_PREPARACION) # carrito / en preparación NO
.prefetch_related(
Prefetch("order_products", queryset=OrderProduct.objects.select_related("product"))
)
Expand All @@ -54,33 +58,72 @@ class OrderTrackView(View):
template_name = "order/order_track.html"

def get(self, request):
# Solo formulario
return render(request, self.template_name, {"order": None, "searched": False})
# Solo muestra el formulario vacío
return render(request, self.template_name, {"searched": False})

def post(self, request):
order_id = request.POST.get("order_id", "").strip()
email = request.POST.get("email", "").strip().lower()

order = None
error = None

if not order_id or not email:
error = "Debes introducir el número de pedido y el email."
else:
try:
order_pk = int(order_id)
order = (
Order.objects.select_related("user")
.prefetch_related(
Prefetch("order_products", queryset=OrderProduct.objects.select_related("product"))
)
.get(pk=order_pk, user__email__iexact=email)
return render(
request,
self.template_name,
{
"searched": True,
"error": "Debes introducir el número de pedido y el email.",
},
)

try:
order_pk = int(order_id)
order = (
Order.objects
.select_related("user")
.prefetch_related(
Prefetch("order_products", queryset=OrderProduct.objects.select_related("product"))
)
except (ValueError, Order.DoesNotExist):
error = "No se ha encontrado ningún pedido con esos datos."
.get(pk=order_pk, user__email__iexact=email)
)
except (ValueError, Order.DoesNotExist):
return render(
request,
self.template_name,
{
"searched": True,
"error": "No se ha encontrado ningún pedido con esos datos.",
},
)

return redirect(f"{reverse('order_detail', kwargs={'pk': order.pk})}?from=track")



return render(
request,
self.template_name,
{"order": order, "searched": True, "error": error},
class OrderDetailView(View):
template_name = "order/order_detail.html"

def get(self, request, pk):
order = (
Order.objects
.select_related("user")
.prefetch_related(
Prefetch("order_products", queryset=OrderProduct.objects.select_related("product"))
)
.filter(pk=pk)
.first()
)

if not order:
raise Http404("Pedido no encontrado")

# ✅ Permitir anónimos SOLO si vienen del seguimiento
if not request.user.is_authenticated:
if request.GET.get("from") == "track":
return render(request, self.template_name, {"order": order})
return redirect("login")

# 🛡 Permisos normales
if request.user.role != "admin" and order.user != request.user:
raise PermissionDenied

return render(request, self.template_name, {"order": order})
Loading