diff --git a/.ruff.toml b/.ruff.toml index ea72e327..11376d54 100644 --- a/.ruff.toml +++ b/.ruff.toml @@ -26,10 +26,11 @@ exclude = [ "node_modules", "site-packages", "venv", - "migrations" + "migrations", + ] -# Same as Black. +#Same as Black. line-length = 88 indent-width = 4 @@ -38,7 +39,10 @@ target-version = "py38" [lint] # Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default. -select = ["E4", "E7", "E9", "F", "COM812", "D102", "D103","I001"] + + +select = ["E4", "E7", "E9", "F", "COM812", "D102", "D103","I001","D101"] + ignore = [] # Allow fix for all enabled rules (when `--fix`) is provided. diff --git a/app/apps.py b/app/apps.py index bcfe39bb..91f36dee 100644 --- a/app/apps.py +++ b/app/apps.py @@ -2,5 +2,10 @@ class AppConfig(AppConfig): + """ + Configuración de la aplicación MyApp. + + Esta clase se encarga de configurar la aplicación MyApp. + """ default_auto_field = "django.db.models.BigAutoField" name = "app" diff --git a/app/migrations/0015_merge_20240604_1813.py b/app/migrations/0015_merge_20240604_1813.py new file mode 100644 index 00000000..4b0bb923 --- /dev/null +++ b/app/migrations/0015_merge_20240604_1813.py @@ -0,0 +1,14 @@ +# Generated by Django 5.0.4 on 2024-06-04 21:13 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0012_alter_product_price'), + ('app', '0014_merge_20240603_0914'), + ] + + operations = [ + ] diff --git a/app/migrations/0015_merge_20240604_1908.py b/app/migrations/0015_merge_20240604_1908.py new file mode 100644 index 00000000..10cbe06e --- /dev/null +++ b/app/migrations/0015_merge_20240604_1908.py @@ -0,0 +1,14 @@ +# Generated by Django 5.0.4 on 2024-06-04 22:08 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0012_alter_product_price'), + ('app', '0014_merge_20240603_0914'), + ] + + operations = [ + ] diff --git a/app/migrations/0016_delete_veterinario.py b/app/migrations/0016_delete_veterinario.py index f610f552..b0511f6d 100644 --- a/app/migrations/0016_delete_veterinario.py +++ b/app/migrations/0016_delete_veterinario.py @@ -1,12 +1,16 @@ + +# Generated by Django 5.0.4 on 2024-06-04 22:08 + # Generated by Django 5.0.4 on 2024-06-03 23:34 + from django.db import migrations class Migration(migrations.Migration): dependencies = [ - ('app', '0015_merge_20240603_1806'), + ('app', '0015_merge_20240604_1908'), ] operations = [ diff --git a/app/models.py b/app/models.py index 8e0e9384..77174c69 100644 --- a/app/models.py +++ b/app/models.py @@ -5,7 +5,10 @@ class CityEnum(models.TextChoices): - LA_PLATA = 'La Plata', + """ + Enumeracion de la Ciudad + """ + LA_PLATA = 'La Plata', BERISSO = 'Berisso', ENSENADA = 'Ensenada', @@ -41,6 +44,9 @@ def validate_client(data): return errors class Client(models.Model): + """ + Modelo que representa a un cliente en el sistema. + """ name = models.CharField(max_length=100) phone = models.CharField(max_length=15) email = models.EmailField() @@ -136,6 +142,9 @@ def validate_provider(data): return errors class Provider(models.Model): + """ + Modelo que representa a un cliente en el sistema. + """ name = models.CharField(max_length=100) email = models.EmailField() address = models.CharField(max_length=100) @@ -190,9 +199,20 @@ def update_provider(self, provider_data): self.name = provider_data.get("name", "") or self.name self.email = provider_data.get("email", "") or self.email self.address = provider_data.get("address", "") or self.address + + + try: + self.save() + return True, None + except Exception as e: + return False, e + + + self.save() return True, None + def validate_product(data): """ Valida los datos del producto. @@ -229,6 +249,9 @@ def validate_product(data): return errors class Product(models.Model): + """ + Modelo que representa a un producto en el sistema. + """ name = models.CharField(max_length=100) product_type = models.CharField(max_length=15) price = models.DecimalField(max_digits=10, decimal_places=2) @@ -333,6 +356,9 @@ def validate_pet(data): return errors class Pet(models.Model): + """ + Modelo que representa a una mascota en el sistema. + """ name = models.CharField(max_length=40) breed = models.CharField(max_length=40) birthday = models.DateField() @@ -429,6 +455,9 @@ def validate_veterinary(data): return errors class Veterinary(models.Model): + """ + Modelo que representa a un veterinario en el sistema. + """ name = models.CharField(max_length=100) email = models.EmailField() phone = models.CharField(max_length=15) @@ -519,6 +548,9 @@ def validate_medicine(data): return errors class Medicine(models.Model): + """ + Modelo que representa una medicina en el sistema. + """ name = models.CharField(max_length=100) description = models.CharField(max_length=255) dose = models.IntegerField() @@ -574,5 +606,14 @@ def update_medicine(self, medicine_data): self.name = medicine_data.get("name", "") or self.name self.description = medicine_data.get("description", "") or self.description self.dose = medicine_data.get("dose", "") or self.dose + + + try: + self.save() + return True, None + except Exception as e: + return False, {"errors": str(e)} + self.save() - return True, None \ No newline at end of file + return True, None + diff --git a/app/tests_integration.py b/app/tests_integration.py index e3543989..def27b3c 100644 --- a/app/tests_integration.py +++ b/app/tests_integration.py @@ -8,6 +8,9 @@ class HomePageTest(TestCase): + """ + Pruebas para la página de inicio. + """ def test_use_home_template(self): """ Esta funcion testea que el template del home funcione. @@ -19,6 +22,9 @@ def test_use_home_template(self): """ class ClientsTest(TestCase): + """ + Pruebas para el repositorio de clientes. + """ def test_repo_use_repo_template(self): """ Esta función testea que el template del repo funcione. @@ -162,6 +168,7 @@ def test_edit_user_with_invalid_data_test_city(self): self.assertEqual(editedClient.city, "La Plata") class MedicineIntegrationTest(TestCase): + """Pruebas de integración para el modelo de Medicina. """ def test_can_create_medicine(self): """ Esta función testea si pudo crear una medicina. @@ -238,6 +245,9 @@ def test_validation_invalid_dose_is_less_than_1(self): ) self.assertContains(response, "La dosis debe estar en un rango de 1 a 10") class ProviderTest(TestCase): + """ + Pruebas para el repositorio de proveedores. + """ def test_repo_use_repo_template(self): """ Esta función verifica que un repositorio está utilizando una plantilla de repositorio específica. @@ -302,6 +312,9 @@ def test_validation_address_null(self): #Agrego una función especifica del issu class PetsTest(TestCase): + """ + Pruebas para el modelo de mascotas. + """ def test_create_pet_with_valid_weight(self): """ Esta función verifica que un sistema permita la creación de una mascota con un peso válido. @@ -404,8 +417,10 @@ def test_create_pet_with_invalid_birthday(self): # Verificar que se muestra un mensaje de error en la respuesta self.assertContains(response, "La fecha de nacimiento debe ser menor a la fecha actual") - class ProductsTest(TestCase): + """ + Pruebas para el modelo de productos. + """ def test_create_product_with_valid_price(self): # Crear un producto con precio válido """ @@ -415,6 +430,7 @@ def test_create_product_with_valid_price(self): reverse("product_form"), data={ "name": "Producto Test", + "product_type": "Tipo Test", "price": "10.00", # Precio válido }, diff --git a/app/tests_unit.py b/app/tests_unit.py index 8de10055..8b2e0217 100644 --- a/app/tests_unit.py +++ b/app/tests_unit.py @@ -5,6 +5,9 @@ class ClientModelTest(TestCase): + """ + Pruebas para el modelo Cliente. + """ def test_can_create_and_get_client(self): """ Prueba la creación y recuperación de un cliente. @@ -99,6 +102,9 @@ def test_update_client_with_email_null(self): #nuevo test verificando que no pue self.assertEqual(client_updated.email, "brujita75@vetsoft.com") class MedicineModelTest(TestCase): + """ + Pruebas para el modelo Medicina. + """ def test_can_create_medicine_with_valid_dose(self): """ @@ -160,6 +166,10 @@ def test_update_medicine_with_invalid_dose(self): self.assertEqual(medicine_updated.dose, 5) class ProviderModelTest(TestCase): + """ + Pruebas para el modelo Provedor. + """ + def test_can_create_and_get_provider(self): """ Prueba la creación y recuperación de un proveedor. @@ -198,6 +208,9 @@ def test_provider_address(self): self.assertEqual(provider.address, addres) #verifica que la direccion recuperada coincida con la especifica class PetModelTest(TestCase): + """ + Pruebas para el modelo Pet. + """ def test_validate_pet_birthday(self): """ Prueba la validación de la fecha de nacimiento de una mascota. @@ -259,6 +272,9 @@ def test_create_pet_with_invalid_weight_negative(self): self.assertEqual(message_or_errors["weight"], "El peso debe ser mayor a cero") class ProductModelTest(TestCase): + """ + Pruebas para el modelo Producto. + """ def test_create_product_with_valid_price(self): """ Prueba la creación de un producto con un precio válido. diff --git a/functional_tests/tests.py b/functional_tests/tests.py index a146c057..fb37d953 100644 --- a/functional_tests/tests.py +++ b/functional_tests/tests.py @@ -15,6 +15,9 @@ class PlaywrightTestCase(StaticLiveServerTestCase): + """ + Clase base para pruebas funcionales utilizando Playwright. + """ @classmethod def setUpClass(cls): """ @@ -49,6 +52,9 @@ def tearDown(self): class HomeTestCase(PlaywrightTestCase): + """ + Pruebas funcionales para la página de inicio. + """ def test_should_have_navbar_with_links(self): """ Esta función verifica que una página web tenga una barra de navegación (navbar) con enlaces (links) a otras páginas o secciones del sitio. @@ -83,6 +89,10 @@ def test_should_have_home_cards_with_links(self): class ClientsRepoTestCase(PlaywrightTestCase): + """ + Pruebas funcionales para la vista de repositorio de clientes. + """ + def test_should_show_message_if_table_is_empty(self): """ Esta función verifica que un mensaje se muestre correctamente cuando una tabla está vacía en una aplicación web. @@ -208,6 +218,9 @@ def is_delete_response(response): class ClientCreateEditTestCase(PlaywrightTestCase): + """ + Pruebas funcionales para crear y editar un cliente. + """ def test_should_be_able_to_create_a_new_client(self): """ Esta función verifica que se pueda crear un nuevo cliente correctamente a través de una solicitud POST al servidor. @@ -301,6 +314,9 @@ def test_should_be_able_to_edit_a_client(self): class MedicineCreateEditTestCase(PlaywrightTestCase): + """ + Pruebas para crear y editar medicamentos. + """ def test_should_show_error_for_dose_greater_than_10(self): """ Esta función verifica que se muestre un mensaje de error cuando se intenta @@ -336,6 +352,9 @@ def test_should_show_error_for_dose_less_than_1(self): expect(self.page.get_by_text("La dosis debe estar en un rango de 1 a 10")).to_be_visible() class ProvidersRepoTestCase(PlaywrightTestCase): + """ + Pruebas para verificar el comportamiento del repositorio de proveedores. + """ def test_should_show_message_if_table_is_empty(self): """ Esta función verifica que se muestre un mensaje adecuado si una tabla en la interfaz de usuario está vacía. @@ -433,6 +452,9 @@ def test_should_be_able_to_edit_a_provider(self): class PetFormCreateValidationTestCase(PlaywrightTestCase): + """ + Pruebas para validar la creación de una mascota en el formulario. + """ def test_should_show_error_for_future_birth_date(self): """ Esta función verifica que se muestre un mensaje de error cuando se intenta @@ -441,6 +463,7 @@ def test_should_show_error_for_future_birth_date(self): self.page.goto(f"{self.live_server_url}{reverse('pet_form')}") expect(self.page.get_by_role("form")).to_be_visible() + # Introduce una fecha de nacimiento no valida future_date = datetime.now().date() + timezone.timedelta(days=7) # Ejemplo: 7 días en el futuro @@ -477,11 +500,13 @@ def test_should_show_error_for_present_birth_date(self): # Verifica si se muestra el mensaje de error esperado expect(self.page.get_by_text("La fecha de nacimiento debe ser menor a la fecha actual")).to_be_visible() + def test_should_be_able_to_create_a_new_pet_goto(self): """ Verifica si el test me permite crear una nueva masota. """ + self.page.goto(f"{self.live_server_url}{reverse('pet_form')}") @@ -543,6 +568,9 @@ def test_should_view_errors_if_form_is_invalid_with_weight_less_than_zero(self): # Pruebas de unidad para verificar la creación exitosa de un nuevo producto class ProductCreatePriceGreaterThanZeroTestCase(PlaywrightTestCase): + """ + Pruebas para verificar la creación de un nuevo producto con un precio mayor que cero. + """ def test_should_be_able_to_create_a_new_product(self): """ Esta función verifica que se pueda crear un nuevo producto correctamente @@ -590,11 +618,7 @@ def test_should_view_errors_if_form_is_invalid_with_price_less_than_zero(self): # Verificar que los mensajes de error para ingresar el nombre y el tipo no sean visibles expect(self.page.get_by_text("Por favor ingrese su nombre")).not_to_be_visible() - expect( - self.page.get_by_text("Por favor ingrese un tipo"), - ).not_to_be_visible() + expect(self.page.get_by_text("Por favor ingrese un tipo")).not_to_be_visible() # Verificar que el mensaje de error "El precio debe ser mayor que cero" sea visible - expect( - self.page.get_by_text("El precio debe ser mayor que cero"), - ).to_be_visible() \ No newline at end of file + expect(self.page.get_by_text("El precio debe ser mayor que cero")).to_be_visible()