From c4788e2faff25bffb45fecd9ff9aa3a4626884b5 Mon Sep 17 00:00:00 2001 From: Alejandro Mantecon Rodriguez Date: Thu, 13 Nov 2025 17:38:37 +0100 Subject: [PATCH 1/4] feat: first version navbar --- essenza/essenza/urls.py | 4 +- essenza/product/views.py | 4 +- essenza/templates/base.html | 312 +++++++++++++++++ essenza/templates/product/dashboard.html | 250 -------------- essenza/templates/product/stock.html | 411 ++++------------------- essenza/templates/user/profile.html | 189 ++--------- essenza/user/tests.py | 26 +- essenza/user/views.py | 14 +- 8 files changed, 429 insertions(+), 781 deletions(-) create mode 100644 essenza/templates/base.html diff --git a/essenza/essenza/urls.py b/essenza/essenza/urls.py index 790c3d47..a32c0642 100644 --- a/essenza/essenza/urls.py +++ b/essenza/essenza/urls.py @@ -3,14 +3,14 @@ from django.contrib import admin from django.urls import include, path from info.views import info_view -from product.views import DashboardView +from product.views import BaseView urlpatterns = [ path("info/", info_view, name="info-home"), path("user/", include("user.urls")), path("admin/", admin.site.urls), path("product/", include("product.urls")), - path("", DashboardView.as_view(), name="dashboard"), + path("", BaseView.as_view(), name="home"), ] if settings.DEBUG: diff --git a/essenza/product/views.py b/essenza/product/views.py index 9d6e6a51..5937a5b8 100644 --- a/essenza/product/views.py +++ b/essenza/product/views.py @@ -6,9 +6,9 @@ from .models import Product -class DashboardView(View): +class BaseView(View): def get(self, request): - return render(request, "product/dashboard.html") + return render(request, "base.html") class StockView(LoginRequiredMixin, UserPassesTestMixin, View): diff --git a/essenza/templates/base.html b/essenza/templates/base.html new file mode 100644 index 00000000..7eeefd1a --- /dev/null +++ b/essenza/templates/base.html @@ -0,0 +1,312 @@ +{% load static %} + + + + + {% block title %}Essenza{% endblock %} + + + + + {% block extra_head %}{% endblock %} + + + +
+ + + + + +
+ + {% block content %}{% endblock %} + + + + {% block extra_js %}{% endblock %} + + diff --git a/essenza/templates/product/dashboard.html b/essenza/templates/product/dashboard.html index 5472c98e..e69de29b 100644 --- a/essenza/templates/product/dashboard.html +++ b/essenza/templates/product/dashboard.html @@ -1,250 +0,0 @@ -{% load static %} - - - - - Escaparate · Essenza - - - - - - - -
- i -
ESSENZA
- - - -
- -
- - - -
- - - - - \ No newline at end of file diff --git a/essenza/templates/product/stock.html b/essenza/templates/product/stock.html index 942db678..22a82442 100644 --- a/essenza/templates/product/stock.html +++ b/essenza/templates/product/stock.html @@ -1,376 +1,79 @@ -{% load static %} - - - - - Escaparate · Essenza - - - - - - -
- i -
ESSENZA
- - - -
- -
- - -
+{% extends 'base.html' %} +{% load static %} -
+{% block title %}Stock · Essenza{% endblock %} + +{% block content %} + + + +
+
{% for p in products %}
{% if p.photo %} - + {{ p.name }} {% else %} - + Imagen por defecto {% endif %}
{{ p.name }}
{% if p.description %} -
{{ p.description }}
- {% endif %} {% if p.category %} -
{{ p.get_category_display }}
+
{{ p.description }}
+ {% endif %} + + {% if p.category %} +
{{ p.get_category_display }}
{% endif %}
- {% with stock_value=p.stock|default:0 %} {% if stock_value <= 0 %} - Agotado (0) - {% elif stock_value <= 10 %} - Stock Bajo: {{ stock_value }} - {% else %} - En Stock: {{ stock_value }} - {% endif %} {% endwith %} + {% with stock_value=p.stock|default:0 %} + {% if stock_value <= 0 %} + Agotado (0) + {% elif stock_value <= 10 %} + Stock Bajo: {{ stock_value }} + {% else %} + En Stock: {{ stock_value }} + {% endif %} + {% endwith %}
-
- {% csrf_token %} - - - -
+ {% if user.is_staff or user.is_superuser %} +
+ {% csrf_token %} + + + +
+ {% endif %}
{% endfor %}
+
- - - +{% endblock %} diff --git a/essenza/templates/user/profile.html b/essenza/templates/user/profile.html index da920e91..594cb4ea 100644 --- a/essenza/templates/user/profile.html +++ b/essenza/templates/user/profile.html @@ -1,162 +1,45 @@ +{% extends "base.html" %} {% load static %} - - - - - Mi Perfil · Essenza - - - - - {% if user.role == "user" %} - Volver - {% else %} - Volver - {% endif %} + -
-

ESSENZA

+
+

ESSENZA

-
- {% if user.photo %} - Foto de perfil - {% else %} - Foto de perfil por defecto - {% endif %} +
+ {% if user.photo %} + Foto de perfil + {% else %} + Foto de perfil por defecto + {% endif %} -
-

Nombre: {{ user.first_name }}

-

Apellidos: {{ user.last_name }}

-

Email: {{ user.email }}

-
- - Editar mis datos - +
+

Nombre: {{ user.first_name }}

+

Apellidos: {{ user.last_name }}

+

Email: {{ user.email }}

+ + Editar mis datos +
- - +
+ +{% endblock %} \ No newline at end of file diff --git a/essenza/user/tests.py b/essenza/user/tests.py index 29aaece7..5a154f97 100644 --- a/essenza/user/tests.py +++ b/essenza/user/tests.py @@ -19,7 +19,7 @@ def setUp(self): username=self.username, email=self.email, password=self.password ) self.login_url = reverse("login") - self.dashboard_url = reverse("dashboard") + self.home_url = reverse("home") # 1. comprueba que la pagina de login carga correctamente def test_get_login_page_returns_200(self): @@ -28,12 +28,12 @@ def test_get_login_page_returns_200(self): self.assertContains(resp, "Iniciar sesión") self.assertContains(resp, "ESSENZA") - # 2. si email y contraseña validas redirige al dashboard - def test_login_with_valid_email_redirects_dashboard(self): + # 2. si email y contraseña validas redirige al home + def test_login_with_valid_email_redirects_home(self): data = {"email": self.email, "password": self.password} resp = self.client.post(self.login_url, data, follow=False) self.assertEqual(resp.status_code, 302, resp.content) - self.assertEqual(resp["Location"], self.dashboard_url) + self.assertEqual(resp["Location"], self.home_url) # 3. si email y contraseña no validas muestra error def test_login_with_invalid_passwordAndEmail_shows_error(self): @@ -60,7 +60,7 @@ def test_login_with_invalid_password_shows_error(self): class RegisterViewTests(TestCase): def setUp(self): self.register_url = reverse("register") - self.dashboard_url = reverse("dashboard") + self.home_url = reverse("home") self.initial_user_count = User.objects.count() # Datos para un nuevo usuario de prueba @@ -80,13 +80,13 @@ def test_get_register_page_returns_200(self): self.assertContains(resp, "Crear cuenta") self.assertContains(resp, "ESSENZA") - # 2. Registro con datos válidos y redirige al dashboard (302) + # 2. Registro con datos válidos y redirige al home (302) def test_successful_registration_redirects_and_creates_user(self): data = self.valid_data.copy() resp = self.client.post(self.register_url, data, follow=False) self.assertEqual(resp.status_code, 302) - self.assertEqual(resp["Location"], self.dashboard_url) + self.assertEqual(resp["Location"], self.home_url) self.assertEqual(User.objects.count(), self.initial_user_count + 1) new_user = User.objects.get(email=data["email"]) @@ -178,10 +178,10 @@ def setUp(self): ) self.login_url = reverse("login") self.logout_url = reverse("logout") - self.dashboard_url = reverse("dashboard") + self.home_url = reverse("home") # 1. Comprobar que un usuario logueado se desloguea y redirige correctamente - def test_logout_redirects_to_dashboard_and_clears_session(self): + def test_logout_redirects_to_home_and_clears_session(self): # Iniciar sesión self.client.login(username="logout@example.com", password="testlogout123") @@ -191,8 +191,8 @@ def test_logout_redirects_to_dashboard_and_clears_session(self): # Hacer logout response = self.client.get(self.logout_url) - # Verificar redirección al dashboard - self.assertRedirects(response, self.dashboard_url) + # Verificar redirección al home + self.assertRedirects(response, self.home_url) # Verificar que se ha cerrado la sesión self.assertNotIn("_auth_user_id", self.client.session) @@ -209,9 +209,9 @@ def test_logout_deletes_session_cookie(self): self.assertTrue( cookie.value == "" or cookie["max-age"] == 0 or cookie["expires"] ) - self.assertRedirects(response, self.dashboard_url) + self.assertRedirects(response, self.home_url) # 3. Comprobar que un usuario no autenticado también redirige correctamente def test_logout_redirects_even_if_not_authenticated(self): response = self.client.get(self.logout_url) - self.assertRedirects(response, self.dashboard_url) + self.assertRedirects(response, self.home_url) diff --git a/essenza/user/views.py b/essenza/user/views.py index 315602d4..e4cdfe26 100644 --- a/essenza/user/views.py +++ b/essenza/user/views.py @@ -11,9 +11,9 @@ class LoginView(View): template_name = "user/login.html" def get(self, request, *args, **kwargs): - # Si el usuario ya está autenticado, lo mandamos a dashboard + # Si el usuario ya está autenticado, lo mandamos a home if request.user.is_authenticated: - return redirect("dashboard") + return redirect("home") # Si no está autenticado, renderiza el formulario de login return render(request, self.template_name, {"form": self.form_class()}) @@ -29,7 +29,7 @@ def post(self, request, *args, **kwargs): if user is not None: login(request, user) if user.role == "user": - return redirect("dashboard") + return redirect("home") else: return redirect("stock") else: @@ -42,13 +42,13 @@ def post(self, request, *args, **kwargs): class LogoutView(View): def get(self, request): logout(request) - response = redirect("dashboard") + response = redirect("home") response.delete_cookie("sessionid") return response def post(self, request): logout(request) - response = redirect("dashboard") + response = redirect("home") response.delete_cookie("sessionid") return response @@ -67,7 +67,7 @@ def post(self, request, *args, **kwargs): if form.is_valid(): user = form.save() login(request, user) - return redirect("dashboard") + return redirect("home") return render(request, self.template_name, {"form": form}) @@ -133,4 +133,4 @@ def post(self, request, *args, **kwargs): if photo_to_delete: photo_to_delete.delete(save=False) - return redirect("dashboard") + return redirect("home") From 61c4b9092e8744ac0ec84b111aaa595644901ea0 Mon Sep 17 00:00:00 2001 From: Alejandro Mantecon Rodriguez Date: Mon, 17 Nov 2025 12:37:18 +0100 Subject: [PATCH 2/4] feat: navbar actualizada --- essenza/templates/base.html | 9 +- essenza/templates/product/catalog.html | 133 +------- essenza/templates/product/dashboard.html | 8 +- essenza/templates/product/detail.html | 134 +++----- essenza/templates/product/detail_user.html | 352 ++++----------------- essenza/templates/product/list.html | 250 ++------------- essenza/user/views.py | 14 +- 7 files changed, 152 insertions(+), 748 deletions(-) diff --git a/essenza/templates/base.html b/essenza/templates/base.html index 78bd8704..81e3c78a 100644 --- a/essenza/templates/base.html +++ b/essenza/templates/base.html @@ -233,14 +233,18 @@
+ @@ -252,9 +256,6 @@
- - - - - + + + +{% endblock %} \ No newline at end of file diff --git a/essenza/templates/product/list.html b/essenza/templates/product/list.html index 1e325c06..ff3d14bc 100644 --- a/essenza/templates/product/list.html +++ b/essenza/templates/product/list.html @@ -1,27 +1,24 @@ +{% extends "base.html" %} + +{% block title %}Lista de Productos · Essenza{% endblock %} + +{% block content %} {% load static %} - - - - - - Lista de Productos - Essenza - - -
-
- i -
ESSENZA
- - -
- -
- - - -
-
- -
+
+ - - - +{% endblock %} \ No newline at end of file diff --git a/essenza/user/views.py b/essenza/user/views.py index e4cdfe26..a0d840cb 100644 --- a/essenza/user/views.py +++ b/essenza/user/views.py @@ -11,9 +11,9 @@ class LoginView(View): template_name = "user/login.html" def get(self, request, *args, **kwargs): - # Si el usuario ya está autenticado, lo mandamos a home + # Si el usuario ya está autenticado, lo mandamos a dashboard if request.user.is_authenticated: - return redirect("home") + return redirect("dashboard") # Si no está autenticado, renderiza el formulario de login return render(request, self.template_name, {"form": self.form_class()}) @@ -29,7 +29,7 @@ def post(self, request, *args, **kwargs): if user is not None: login(request, user) if user.role == "user": - return redirect("home") + return redirect("dashboard") else: return redirect("stock") else: @@ -42,13 +42,13 @@ def post(self, request, *args, **kwargs): class LogoutView(View): def get(self, request): logout(request) - response = redirect("home") + response = redirect("dashboard") response.delete_cookie("sessionid") return response def post(self, request): logout(request) - response = redirect("home") + response = redirect("dashboard") response.delete_cookie("sessionid") return response @@ -67,7 +67,7 @@ def post(self, request, *args, **kwargs): if form.is_valid(): user = form.save() login(request, user) - return redirect("home") + return redirect("dashboard") return render(request, self.template_name, {"form": form}) @@ -133,4 +133,4 @@ def post(self, request, *args, **kwargs): if photo_to_delete: photo_to_delete.delete(save=False) - return redirect("home") + return redirect("dashboard") \ No newline at end of file From 3af5535de28640fee34b0d1623e10f5bc9b81771 Mon Sep 17 00:00:00 2001 From: Celia Date: Mon, 17 Nov 2025 12:55:44 +0100 Subject: [PATCH 3/4] Arreglo de fallos de stock.html --- essenza/product/tests.py | 8 +- essenza/templates/product/stock.html | 358 +++++++++++++-------------- 2 files changed, 183 insertions(+), 183 deletions(-) diff --git a/essenza/product/tests.py b/essenza/product/tests.py index 248dc3b3..6bf1658d 100644 --- a/essenza/product/tests.py +++ b/essenza/product/tests.py @@ -328,13 +328,13 @@ def test_admin_can_access_detail(self): def test_admin_can_create_product(self): """Prueba que un admin puede crear un nuevo producto (POST).""" self.client.force_login(self.admin) - + initial_count = Product.objects.count() data = { "name": "Nuevo Producto Creado", "description": "Creado por el test de admin", - "category": "perfume", + "category": "perfume", "brand": "NewBrand", "price": "99.99", "stock": 100, @@ -355,7 +355,7 @@ def test_admin_can_update_product(self): data = { "name": updated_name, "description": "Descripción actualizada", - "category": "tratamiento", + "category": "tratamiento", "brand": self.product.brand, "price": updated_price, "stock": 50, @@ -365,7 +365,7 @@ def test_admin_can_update_product(self): self.assertEqual(resp.status_code, 302) self.assertRedirects(resp, reverse("product_list")) - + self.product.refresh_from_db() self.assertEqual(self.product.name, updated_name) self.assertEqual(self.product.price, Decimal(updated_price)) diff --git a/essenza/templates/product/stock.html b/essenza/templates/product/stock.html index 50ce9116..70edfee2 100644 --- a/essenza/templates/product/stock.html +++ b/essenza/templates/product/stock.html @@ -1,184 +1,184 @@ - -{% extends 'base.html' %} -{% load static %} - -{% block title %}Stock · Essenza{% endblock %} - -{% block content %} - - - - - -
- {% for p in products %} -
- {% if p.photo %} - {{ p.name }} - {% else %} - +{% extends 'base.html' %} {% load static %} {% block title %}Stock · +Essenza{%endblock %} {% block content %} + + + + +
+ {% for p in products %} +
+ {% if p.photo %} + {{ p.name }} + {% else %} + + {% endif %} + +
+
{{ p.name }}
+ + {% if p.description %} +
{{ p.description }}
+ {% endif %} {% if p.category %} +
{{ p.get_category_display }}
{% endif %} -
-
{{ p.name }}
- - {% if p.description %} -
{{ p.description }}
- {% endif %} - - {% if p.category %} -
{{ p.get_category_display }}
- {% endif %} - -
- {% with stock_value=p.stock|default:0 %} - {% if stock_value <= 0 %} - Agotado (0) - {% elif stock_value <= 10 %} - Stock Bajo: {{ stock_value }} - {% else %} - En Stock: {{ stock_value }} - {% endif %} - {% endwith %} -
- - {% if user.is_staff or user.is_superuser %} -
- {% csrf_token %} - - - -
- {% endif %} +
+ {% with stock_value=p.stock|default:0 %} {% if stock_value <= 0 %} + Agotado (0) + {% elif stock_value <= 10 %} + Stock Bajo: {{ stock_value }} + {% else %} + En Stock: {{ stock_value }} + {% endif %} {% endwith %}
+ + {% if user.is_staff or user.is_superuser %} +
+ {% csrf_token %} + + + +
+ {% endif %}
- {% endfor %} -
-
+
+ {% endfor %} +
-{% endblock %} + {% endblock %} + From 3da3adf965c7282fa1071eca77133d854e074253 Mon Sep 17 00:00:00 2001 From: Celia Date: Mon, 17 Nov 2025 13:50:10 +0100 Subject: [PATCH 4/4] Arreglos de tests de user --- essenza/product/forms.py | 12 +++++++++++- essenza/product/urls.py | 10 +++++----- essenza/product/views.py | 6 +++--- essenza/user/tests.py | 26 +++++++++++++------------- essenza/user/views.py | 2 +- 5 files changed, 33 insertions(+), 23 deletions(-) diff --git a/essenza/product/forms.py b/essenza/product/forms.py index b3ddef97..c9369a99 100644 --- a/essenza/product/forms.py +++ b/essenza/product/forms.py @@ -1,8 +1,18 @@ from django import forms + from .models import Product class ProductForm(forms.ModelForm): class Meta: model = Product - fields = ['name', 'description', 'category', 'brand', 'price', 'photo', 'stock', 'is_active'] + fields = [ + "name", + "description", + "category", + "brand", + "price", + "photo", + "stock", + "is_active", + ] diff --git a/essenza/product/urls.py b/essenza/product/urls.py index 83d25b73..dfa067db 100644 --- a/essenza/product/urls.py +++ b/essenza/product/urls.py @@ -6,11 +6,11 @@ urlpatterns = [ path("stock/", views.StockView.as_view(), name="stock"), - path('', views.ProductListView.as_view(), name='product_list'), - path('create/', views.ProductCreateView.as_view(), name='product_create'), - path('/', views.ProductDetailView.as_view(), name='product_detail'), - path('/edit/', views.ProductUpdateView.as_view(), name='product_update'), - path('/delete/', views.ProductDeleteView.as_view(), name='product_delete'), + path("", views.ProductListView.as_view(), name="product_list"), + path("create/", views.ProductCreateView.as_view(), name="product_create"), + path("/", views.ProductDetailView.as_view(), name="product_detail"), + path("/edit/", views.ProductUpdateView.as_view(), name="product_update"), + path("/delete/", views.ProductDeleteView.as_view(), name="product_delete"), ] if settings.DEBUG: diff --git a/essenza/product/views.py b/essenza/product/views.py index 28474abe..783a03f2 100644 --- a/essenza/product/views.py +++ b/essenza/product/views.py @@ -4,16 +4,16 @@ from django.shortcuts import get_object_or_404, redirect, render from django.utils import timezone from django.views import View -from .forms import ProductForm -from order.models import OrderProduct -from .models import Product + from .forms import ProductForm from .models import Product + class BaseView(View): def get(self, request): return render(request, "base.html") + class DashboardView(UserPassesTestMixin, View): template_name = "product/dashboard.html" diff --git a/essenza/user/tests.py b/essenza/user/tests.py index 5a154f97..29aaece7 100644 --- a/essenza/user/tests.py +++ b/essenza/user/tests.py @@ -19,7 +19,7 @@ def setUp(self): username=self.username, email=self.email, password=self.password ) self.login_url = reverse("login") - self.home_url = reverse("home") + self.dashboard_url = reverse("dashboard") # 1. comprueba que la pagina de login carga correctamente def test_get_login_page_returns_200(self): @@ -28,12 +28,12 @@ def test_get_login_page_returns_200(self): self.assertContains(resp, "Iniciar sesión") self.assertContains(resp, "ESSENZA") - # 2. si email y contraseña validas redirige al home - def test_login_with_valid_email_redirects_home(self): + # 2. si email y contraseña validas redirige al dashboard + def test_login_with_valid_email_redirects_dashboard(self): data = {"email": self.email, "password": self.password} resp = self.client.post(self.login_url, data, follow=False) self.assertEqual(resp.status_code, 302, resp.content) - self.assertEqual(resp["Location"], self.home_url) + self.assertEqual(resp["Location"], self.dashboard_url) # 3. si email y contraseña no validas muestra error def test_login_with_invalid_passwordAndEmail_shows_error(self): @@ -60,7 +60,7 @@ def test_login_with_invalid_password_shows_error(self): class RegisterViewTests(TestCase): def setUp(self): self.register_url = reverse("register") - self.home_url = reverse("home") + self.dashboard_url = reverse("dashboard") self.initial_user_count = User.objects.count() # Datos para un nuevo usuario de prueba @@ -80,13 +80,13 @@ def test_get_register_page_returns_200(self): self.assertContains(resp, "Crear cuenta") self.assertContains(resp, "ESSENZA") - # 2. Registro con datos válidos y redirige al home (302) + # 2. Registro con datos válidos y redirige al dashboard (302) def test_successful_registration_redirects_and_creates_user(self): data = self.valid_data.copy() resp = self.client.post(self.register_url, data, follow=False) self.assertEqual(resp.status_code, 302) - self.assertEqual(resp["Location"], self.home_url) + self.assertEqual(resp["Location"], self.dashboard_url) self.assertEqual(User.objects.count(), self.initial_user_count + 1) new_user = User.objects.get(email=data["email"]) @@ -178,10 +178,10 @@ def setUp(self): ) self.login_url = reverse("login") self.logout_url = reverse("logout") - self.home_url = reverse("home") + self.dashboard_url = reverse("dashboard") # 1. Comprobar que un usuario logueado se desloguea y redirige correctamente - def test_logout_redirects_to_home_and_clears_session(self): + def test_logout_redirects_to_dashboard_and_clears_session(self): # Iniciar sesión self.client.login(username="logout@example.com", password="testlogout123") @@ -191,8 +191,8 @@ def test_logout_redirects_to_home_and_clears_session(self): # Hacer logout response = self.client.get(self.logout_url) - # Verificar redirección al home - self.assertRedirects(response, self.home_url) + # Verificar redirección al dashboard + self.assertRedirects(response, self.dashboard_url) # Verificar que se ha cerrado la sesión self.assertNotIn("_auth_user_id", self.client.session) @@ -209,9 +209,9 @@ def test_logout_deletes_session_cookie(self): self.assertTrue( cookie.value == "" or cookie["max-age"] == 0 or cookie["expires"] ) - self.assertRedirects(response, self.home_url) + self.assertRedirects(response, self.dashboard_url) # 3. Comprobar que un usuario no autenticado también redirige correctamente def test_logout_redirects_even_if_not_authenticated(self): response = self.client.get(self.logout_url) - self.assertRedirects(response, self.home_url) + self.assertRedirects(response, self.dashboard_url) diff --git a/essenza/user/views.py b/essenza/user/views.py index a0d840cb..315602d4 100644 --- a/essenza/user/views.py +++ b/essenza/user/views.py @@ -133,4 +133,4 @@ def post(self, request, *args, **kwargs): if photo_to_delete: photo_to_delete.delete(save=False) - return redirect("dashboard") \ No newline at end of file + return redirect("dashboard")