From 90995e4b306b55853d99c8b433502fe7aec671eb Mon Sep 17 00:00:00 2001 From: FRANCISCO DE CASTRO Date: Thu, 6 Nov 2025 20:55:53 +0100 Subject: [PATCH 1/5] =?UTF-8?q?Funcionalidad=20de=20registro=20a=C3=B1adid?= =?UTF-8?q?a?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- essenza/essenza/settings.py | 2 +- essenza/essenza/urls.py | 5 +- essenza/templates/user/register.html | 163 +++++++++++++++++++++++++++ essenza/user/forms.py | 35 ++++++ essenza/user/urls.py | 10 ++ essenza/user/views.py | 30 ++++- 6 files changed, 241 insertions(+), 4 deletions(-) create mode 100644 essenza/templates/user/register.html create mode 100644 essenza/user/forms.py create mode 100644 essenza/user/urls.py diff --git a/essenza/essenza/settings.py b/essenza/essenza/settings.py index f1a04d8b..3ec16880 100644 --- a/essenza/essenza/settings.py +++ b/essenza/essenza/settings.py @@ -57,7 +57,7 @@ TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], + 'DIRS': [BASE_DIR / 'templates'], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ diff --git a/essenza/essenza/urls.py b/essenza/essenza/urls.py index 80e86799..0708ec05 100644 --- a/essenza/essenza/urls.py +++ b/essenza/essenza/urls.py @@ -1,7 +1,9 @@ from django.contrib import admin -from django.urls import path +from django.urls import include, path from django.http import HttpResponse +import user + def home(request): html = """ @@ -37,6 +39,7 @@ def home(request): urlpatterns = [ path('', home, name='home'), + path('user/', include('user.urls')), path('admin/', admin.site.urls), ] diff --git a/essenza/templates/user/register.html b/essenza/templates/user/register.html new file mode 100644 index 00000000..fa41fd6d --- /dev/null +++ b/essenza/templates/user/register.html @@ -0,0 +1,163 @@ + + + + + + Registro - Essenza + + + + + + + +
+
+ + + +
+ +
+ + {% csrf_token %} + + {{ form.name.label_tag }} + {{ form.name }} + + + {{ form.email.label_tag }} + {{ form.email }} + + {{ form.foto.label_tag }} + {{ form.foto }} + + {{ form.username.label_tag }} + {{ form.username }} + + {{ form.password.label_tag }} + {{ form.password }} + + {% if form.errors %} +
+

Por favor, corrige los errores:

+ {{ form.non_field_errors }} + + {% for field in form %} + {% if field.errors %} + {{ field.label }}: {{ field.errors|striptags }} + {% endif %} + {% endfor %} +
+ {% endif %} + + +
+
+ + + \ No newline at end of file diff --git a/essenza/user/forms.py b/essenza/user/forms.py new file mode 100644 index 00000000..b77f305a --- /dev/null +++ b/essenza/user/forms.py @@ -0,0 +1,35 @@ +# user/forms.py (Crea este archivo) +from django import forms +from .models import Usuario # Importa tu modelo User personalizado + +class RegisterForm(forms.ModelForm): + """ + Formulario de registro personalizado basado en el mockup. + """ + class Meta: + model = Usuario + + # Campos que se pedirán en el formulario + fields = [ + 'name', # Corresponde a 'Nombre' + 'email', # Corresponde a 'Correo electrónico' + 'foto', # El nuevo campo 'Foto' + 'password', # Contraseña + ] + + # Etiquetas para que coincidan 100% con el mockup + labels = { + 'name': 'Nombre', + 'email': 'Correo electrónico', + 'foto': 'Foto', + 'password': 'Contraseña', + } + + def _init_(self, *args, **kwargs): + super(RegisterForm, self)._init_(*args, **kwargs) + + # Hacemos que 'Nombre', 'Email' y 'Contraseña' sean obligatorios + self.fields['name'].required = True + self.fields['email'].required = True + self.fields['foto'].required = False # 'Foto' es opcional + self.fields['password'].required = True \ No newline at end of file diff --git a/essenza/user/urls.py b/essenza/user/urls.py new file mode 100644 index 00000000..3f33ab57 --- /dev/null +++ b/essenza/user/urls.py @@ -0,0 +1,10 @@ +from django.contrib import admin +from django.urls import include, path +from django.http import HttpResponse +import user.views as views + + +urlpatterns = [ + path('register/', views.RegisterView.as_view(), name='register'), +] + diff --git a/essenza/user/views.py b/essenza/user/views.py index 91ea44a2..62956323 100644 --- a/essenza/user/views.py +++ b/essenza/user/views.py @@ -1,3 +1,29 @@ -from django.shortcuts import render - # Create your views here. +from django.shortcuts import render, redirect +from django.views import View +from .forms import RegisterForm +import templates + +class RegisterView(View): + """ + Controla el registro de usuarios. + """ + form_class = RegisterForm + # El archivo HTML que debe renderizar esta vista + template_name = 'user/register.html' + + def get(self, request, *args, **kwargs): + # Muestra el formulario vacío + form = self.form_class() + return render(request, self.template_name, {'form': form}) + + def post(self, request, *args, **kwargs): + form = self.form_class(request.POST, request.FILES) + + if form.is_valid(): + user = form.save() # Guarda el nuevo usuario en la BBDD + + # Redirige a la página principal (definida como 'home' en info/urls.py) + return redirect('home') + + return render(request, self.template_name, {'form': form}) \ No newline at end of file From a9c176daacc3e3787f5a9138bbb47c8e56deb17c Mon Sep 17 00:00:00 2001 From: Celia Date: Sat, 8 Nov 2025 22:10:52 +0100 Subject: [PATCH 2/5] Base de datos actualizada --- essenza/db.sqlite3 => db.sqlite3 | Bin 208896 -> 176128 bytes 1 file changed, 0 insertions(+), 0 deletions(-) rename essenza/db.sqlite3 => db.sqlite3 (71%) diff --git a/essenza/db.sqlite3 b/db.sqlite3 similarity index 71% rename from essenza/db.sqlite3 rename to db.sqlite3 index 979deb74ca51f5b91dd207f44afeabb6a18b7949..a07469daa4de7d124114b580ddfa56080b71ee18 100644 GIT binary patch literal 176128 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 literal 208896 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 Date: Sat, 8 Nov 2025 22:17:53 +0100 Subject: [PATCH 3/5] Muevo la base de datos a su sitio correcto --- db.sqlite3 => essenza/db.sqlite3 | Bin 176128 -> 176128 bytes 1 file changed, 0 insertions(+), 0 deletions(-) rename db.sqlite3 => essenza/db.sqlite3 (99%) diff --git a/db.sqlite3 b/essenza/db.sqlite3 similarity index 99% rename from db.sqlite3 rename to essenza/db.sqlite3 index a07469daa4de7d124114b580ddfa56080b71ee18..836a999a694fb44e7f735d79c350ef632636facc 100644 GIT binary patch delta 531 zcmZp8z}4`8Yl1YR&qNt#MxTud%i`HKGw_FTZ{Ez4u$)_{(VdB(q0!!vLtI=^o0HR6 zRC}^PUXq}Nf{~$>p}CcTnVy-kv9W>0WWjv5=DM8ibvcY}hq;(}rZDi`S=t#!gY;6?wtV^-h^#z9C+TUY3=vnfc{mUQQmlKAz5&0lGe(eijy1 zhGiawUItc)29*{mKJmV$$ytRtp*dy+o(55gmIh9q9^OF#S>8t8B~HmXk>%m073oF> zMy9%khPp;ZNWo@mX>MZHq{IXcnACD3v&!sJ3-k1}^zCPDnar8EnE59$@K563&VOgK zVnGYPrV6t!BcbqP1}U0;(3VMI`fYzEO`sV|82BIYALd^IG-DdSyd1M5BW}kqZ$BK* HWE%hg*eIc& delta 129 zcmV-{0Dk{~;0l1?3XmHCNs$~w0ZFl7re6lS01s9Ry0Z*mrwfr#2MB>c0uKOzKQoiN zYiyGTZ%~7NY`1=F0fxf}0u8wU4&Dv9vmqd@4Y#>H0!so20uQ$U54R88vmtP+4+JCw jO#zp|Jpv$?+fM>12m%ko01x61!?O{9w-2|&UjjW)60|Eg From 69f109452f411bdda833a9554017a6e4572df023 Mon Sep 17 00:00:00 2001 From: Celia Date: Sat, 8 Nov 2025 22:24:56 +0100 Subject: [PATCH 4/5] Correccion de vista del escaparate como invitado --- essenza/templates/product/escaparate.html | 26 +++++++++++++++-------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/essenza/templates/product/escaparate.html b/essenza/templates/product/escaparate.html index d76efeca..5fbbd77b 100644 --- a/essenza/templates/product/escaparate.html +++ b/essenza/templates/product/escaparate.html @@ -105,18 +105,26 @@ - -
+
ESSENZA
-
- {% csrf_token %} - -
-
- - + {% if user.is_authenticated %} + +
+ {% csrf_token %} + +
+ + {% else %} + + + Log in + + + {% endif %} +
+ \ No newline at end of file From 1a0fa3be96a4dac0facca3a5142e0c8f37e6078f Mon Sep 17 00:00:00 2001 From: Celia Date: Sun, 9 Nov 2025 09:16:04 +0100 Subject: [PATCH 5/5] Tests de registro creados correctamente --- essenza/essenza/settings.py | 4 +- essenza/user/tests.py | 122 ++++++++++++++++++++++++++++++++++-- 2 files changed, 120 insertions(+), 6 deletions(-) diff --git a/essenza/essenza/settings.py b/essenza/essenza/settings.py index 82d2accb..662ee0e4 100644 --- a/essenza/essenza/settings.py +++ b/essenza/essenza/settings.py @@ -46,6 +46,7 @@ MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.locale.LocaleMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', @@ -63,6 +64,7 @@ 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.request', + 'django.template.context_processors.i18n', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], @@ -106,7 +108,7 @@ # Internationalization # https://docs.djangoproject.com/en/5.2/topics/i18n/ -LANGUAGE_CODE = 'en-us' +LANGUAGE_CODE = 'es' TIME_ZONE = 'UTC' diff --git a/essenza/user/tests.py b/essenza/user/tests.py index f6d5c175..52594eab 100644 --- a/essenza/user/tests.py +++ b/essenza/user/tests.py @@ -1,11 +1,12 @@ -from django.test import TestCase - -# Create your tests here. -# user/tests/test_login.py +import tempfile from django.test import TestCase from django.urls import reverse from django.contrib.auth import get_user_model from django.conf import settings +from django.core.files.uploadedfile import SimpleUploadedFile +import io +import os + User = get_user_model() @@ -20,7 +21,7 @@ def setUp(self): email=self.email, password=self.password ) - self.login_url = reverse("user:login") + self.login_url = reverse("login") self.home_url = reverse("home") self.escaparate_url = reverse("escaparate") @@ -58,3 +59,114 @@ def test_login_with_invalid_password_shows_error(self): resp = self.client.post(self.login_url, data) self.assertEqual(resp.status_code, 200) self.assertContains(resp, "Usuario o contraseña incorrectos") + + +class RegisterViewTests(TestCase): + def setUp(self): + self.register_url = reverse("register") + self.escaparate_url = reverse("escaparate") + self.initial_user_count = User.objects.count() + + # Datos para un nuevo usuario de prueba + self.valid_data = { + 'first_name': 'Juan', + 'last_name': 'Perez', + 'username': 'nuevo_usuario', + 'email': 'nuevo@ejemplo.com', + 'password1': 'PasswordSeguro123', + 'password2': 'PasswordSeguro123', + } + + #1. Comprueba que la página de registro carga correctamente + def test_get_register_page_returns_200(self): + resp = self.client.get(self.register_url) + self.assertEqual(resp.status_code, 200) + self.assertContains(resp, "Crear cuenta") + self.assertContains(resp, "ESSENZA") + + #2. Registro con datos válidos y redirige al escaparate (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.escaparate_url) + self.assertEqual(User.objects.count(), self.initial_user_count + 1) + + new_user = User.objects.get(email=data['email']) + self.assertTrue(new_user.check_password(data['password1'])) # La contraseña está hasheada + + + #3. Registro con email duplicado muestra error + def test_registration_with_duplicate_email_shows_error(self): + User.objects.create_user(username='test', email=self.valid_data['email'], password='test') # Usuario previo creado con mismo email + data = self.valid_data.copy() + resp = self.client.post(self.register_url, data) #Intento de registro con el mismo email + + self.assertEqual(User.objects.count(), self.initial_user_count + 1) #Solo se añade el usuario creado antes + self.assertContains(resp, "Ya existe Usuario con este Email.", html=True) + + + #4. Registro con contraseñas que no coinciden muestra error + def test_registration_with_mismatched_passwords_shows_error(self): + data = self.valid_data.copy() + data['password2'] = 'diferente123' + resp = self.client.post(self.register_url, data) + + self.assertEqual(User.objects.count(), self.initial_user_count) + self.assertContains(resp, "Los dos campos de contraseña no coinciden.") + + + #5. Registro con campo 'first_name' vacío muestra error (required=True) + def test_registration_missing_first_name_shows_error(self): + data = self.valid_data.copy() + data['first_name'] = '' + resp = self.client.post(self.register_url, data) + + self.assertEqual(User.objects.count(), self.initial_user_count) + self.assertContains(resp, "Este campo es obligatorio.") + + + #6. Registro con subida de foto válida + def test_registration_with_valid_photo(self): + # Creo una foto JPEG en memoria + try: + from PIL import Image + buf = io.BytesIO() + img = Image.new('RGB', (1, 1), color=(255, 0, 0)) + img.save(buf, format='JPEG') + image_data = buf.getvalue() + except Exception: + self.skipTest('Pillow is required to create a test JPEG image') + + photo = SimpleUploadedFile( + name='test_photo.jpg', + content=image_data, + content_type='image/jpeg' + ) + + data = self.valid_data.copy() + data['foto'] = photo + resp = self.client.post(self.register_url, data, follow=False) + + self.assertEqual(resp.status_code, 302) + new_user = User.objects.get(email=data['email']) + self.assertTrue(new_user.foto.name.startswith('images/test_photo')) + + # Elimina la foto creada + if new_user.foto: + if os.path.exists(new_user.foto.path): + os.remove(new_user.foto.path) + + + #7. Registro sin campo 'foto' (opcional) es exitoso + def test_registration_without_photo_is_successful(self): + data = self.valid_data.copy() + if 'foto' in data: + del data['foto'] + + resp = self.client.post(self.register_url, data, follow=False) + + self.assertEqual(resp.status_code, 302) + new_user = User.objects.get(email=data['email']) + self.assertFalse(new_user.foto) \ No newline at end of file