From e57740df44e97fe39768446047f2857ed6d7dae1 Mon Sep 17 00:00:00 2001 From: AdalbertoCV <34152734@uaz.edu.mx> Date: Mon, 9 Sep 2024 20:27:05 -0600 Subject: [PATCH] Apertura y cierre de convocatoria implementado. --- cosiap_api/administracion/admin.py | 3 +- .../0001_crear_modelo_convocatoria.py | 22 ++++++ .../0002_eliminar_columna_nombre.py | 17 +++++ .../0003_crear_modelo_configuracion_diseno.py | 23 ++++++ cosiap_api/administracion/models.py | 16 ++++- cosiap_api/administracion/tests.py | 70 ++++++++++++++++++- cosiap_api/administracion/urls.py | 4 +- cosiap_api/administracion/views.py | 64 ++++++++++++++++- 8 files changed, 214 insertions(+), 5 deletions(-) create mode 100644 cosiap_api/administracion/migrations/0001_crear_modelo_convocatoria.py create mode 100644 cosiap_api/administracion/migrations/0002_eliminar_columna_nombre.py create mode 100644 cosiap_api/administracion/migrations/0003_crear_modelo_configuracion_diseno.py diff --git a/cosiap_api/administracion/admin.py b/cosiap_api/administracion/admin.py index 8c38f3f..b8f0384 100644 --- a/cosiap_api/administracion/admin.py +++ b/cosiap_api/administracion/admin.py @@ -1,3 +1,4 @@ from django.contrib import admin +from .models import Convocatoria -# Register your models here. +admin.site.register(Convocatoria) diff --git a/cosiap_api/administracion/migrations/0001_crear_modelo_convocatoria.py b/cosiap_api/administracion/migrations/0001_crear_modelo_convocatoria.py new file mode 100644 index 0000000..51422bc --- /dev/null +++ b/cosiap_api/administracion/migrations/0001_crear_modelo_convocatoria.py @@ -0,0 +1,22 @@ +# Generated by Django 5.0.8 on 2024-09-07 18:33 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Convocatoria', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('nombre', models.CharField(max_length=100)), + ('abierta', models.BooleanField(default=False)), + ], + ), + ] diff --git a/cosiap_api/administracion/migrations/0002_eliminar_columna_nombre.py b/cosiap_api/administracion/migrations/0002_eliminar_columna_nombre.py new file mode 100644 index 0000000..174ddb9 --- /dev/null +++ b/cosiap_api/administracion/migrations/0002_eliminar_columna_nombre.py @@ -0,0 +1,17 @@ +# Generated by Django 5.0.8 on 2024-09-07 19:01 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('administracion', '0001_crear_modelo_convocatoria'), + ] + + operations = [ + migrations.RemoveField( + model_name='convocatoria', + name='nombre', + ), + ] diff --git a/cosiap_api/administracion/migrations/0003_crear_modelo_configuracion_diseno.py b/cosiap_api/administracion/migrations/0003_crear_modelo_configuracion_diseno.py new file mode 100644 index 0000000..776342d --- /dev/null +++ b/cosiap_api/administracion/migrations/0003_crear_modelo_configuracion_diseno.py @@ -0,0 +1,23 @@ +# Generated by Django 5.0.8 on 2024-09-10 02:15 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('administracion', '0002_eliminar_columna_nombre'), + ] + + operations = [ + migrations.CreateModel( + name='ConfiguracionEstilo', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('logo', models.ImageField(blank=True, null=True, upload_to='logos/')), + ('color_primario', models.CharField(help_text='Formato HEX, ej. #FFFFFF', max_length=7)), + ('color_secundario', models.CharField(help_text='Formato HEX, ej. #000000', max_length=7)), + ('color_fondo', models.CharField(help_text='Formato HEX, ej. #F0F0F0', max_length=7)), + ], + ), + ] diff --git a/cosiap_api/administracion/models.py b/cosiap_api/administracion/models.py index 71a8362..85b2a16 100644 --- a/cosiap_api/administracion/models.py +++ b/cosiap_api/administracion/models.py @@ -1,3 +1,17 @@ from django.db import models -# Create your models here. +class Convocatoria(models.Model): + ''' + Modelo que guardará los datos de una convocatoria + ''' + abierta = models.BooleanField(default=False) + + +class ConfiguracionEstilo(models.Model): + logo = models.ImageField(upload_to='logos/', blank=True, null=True) + color_primario = models.CharField(max_length=7, help_text='Formato HEX, ej. #FFFFFF') + color_secundario = models.CharField(max_length=7, help_text='Formato HEX, ej. #000000') + color_fondo = models.CharField(max_length=7, help_text='Formato HEX, ej. #F0F0F0') + + def __str__(self): + return f"Configuración de diseño - ID: {self.id}" \ No newline at end of file diff --git a/cosiap_api/administracion/tests.py b/cosiap_api/administracion/tests.py index 7ce503c..d935759 100644 --- a/cosiap_api/administracion/tests.py +++ b/cosiap_api/administracion/tests.py @@ -1,3 +1,71 @@ from django.test import TestCase +from django.urls import reverse +from rest_framework.test import APIClient +from rest_framework import status +from users.models import Usuario, Municipio, Estado +from .models import Convocatoria -# Create your tests here. +class ConvocatoriaTest(TestCase): + ''' + Clase para probar la funcionalidad de cambio de estado de la convocatoria + ''' + + def setUp(self): + """Configurar el entorno de prueba""" + self.client = APIClient() + self.usuario_data = { + 'curp': 'CEVA020423HGRRZDA8', + 'nombre': 'Adalberto', + 'email': 'adalc3488@gmail.com', + 'password': 'testpassword123' + } + self.usuario = Usuario.objects.create_superuser(**self.usuario_data) + self.usuario.is_active = True + self.usuario.is_staff = True + self.usuario.save() + + # Iniciar sesión + self.login_url = reverse('users:token_obtain') + response = self.client.post(self.login_url, { + 'curp': self.usuario_data['curp'], + 'password': self.usuario_data['password'] + }) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.access_token = response.data['access'] + self.client.credentials(HTTP_AUTHORIZATION=f'Bearer {self.access_token}') + + # Configurar cookie de refresh token + refresh_token = response.cookies.get('refresh_token') + if refresh_token: + self.client.cookies['refresh_token'] = refresh_token.value + + + def test_abrir_convocatoria(self): + ''' Prueba para probar la apertura de una convocatoria''' + + url = reverse('administracion:convocatoria') + + data = { + "nuevo_estado": True + } + + response = self.client.put(url, data, format='json') + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertIn('success', response.data['messages']) + self.assertEqual(response.data['messages']['success'][0], 'Estado de la convocatoria actualizado.') + response = self.client.get(url) + self.assertEqual(response.data['convocatoria_is_open'], True) + + def test_cerrar_convocatoria(self): + url = reverse('administracion:convocatoria') + + data = { + "nuevo_estado": False + } + + response = self.client.put(url, data, format='json') + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertIn('success', response.data['messages']) + self.assertEqual(response.data['messages']['success'][0], 'Estado de la convocatoria actualizado.') + response = self.client.get(url) + self.assertEqual(response.data['convocatoria_is_open'], False) diff --git a/cosiap_api/administracion/urls.py b/cosiap_api/administracion/urls.py index 3a22da4..60733c2 100644 --- a/cosiap_api/administracion/urls.py +++ b/cosiap_api/administracion/urls.py @@ -4,4 +4,6 @@ from django.contrib.auth import views as auth_views app_name = 'administracion' -urlpatterns = [] \ No newline at end of file +urlpatterns = [ + path('convocatoria/', views.AbrirCerrarConvocatoria.as_view(), name='convocatoria'), + ] \ No newline at end of file diff --git a/cosiap_api/administracion/views.py b/cosiap_api/administracion/views.py index 91ea44a..af693e0 100644 --- a/cosiap_api/administracion/views.py +++ b/cosiap_api/administracion/views.py @@ -1,3 +1,65 @@ from django.shortcuts import render +from common.views import BasePermissionAPIView +from rest_framework.permissions import IsAuthenticated +from users.permisos import es_admin +from rest_framework import status +from .models import Convocatoria +from rest_framework.response import Response +from notificaciones.mensajes import Mensaje -# Create your views here. +class AbrirCerrarConvocatoria(BasePermissionAPIView): + ''' + APIView con la lógica para abrir la convocatoria. + ''' + + permission_classes_list = [IsAuthenticated, es_admin] + permission_classes_update = [IsAuthenticated, es_admin] + + def get(self, request, *args, **kwargs): + ''' + Método get para obtener el estado actual de la convocatoria + ''' + + data = {} + + convocatoria = Convocatoria.objects.all().first() + + if convocatoria: + data['convocatoria_is_open'] = convocatoria.abierta + else: + data['convocatoria_is_open'] = False + return Response(data, status = status.HTTP_200_OK) + + + def put(self, request, *args, **kwargs): + ''' + Método para la edición de el estado de una convocatoria + ''' + data = {} + try: + + data = {} + + estado = request.data.get('nuevo_estado') + + convocatoria = Convocatoria.objects.all().first() + + if convocatoria: + convocatoria.abierta = estado + convocatoria.save() + else: + convocatoria = Convocatoria.objects.create( + abierta = estado + ) + + Mensaje.success(data, 'Estado de la convocatoria actualizado.') + return Response(data, status = status.HTTP_200_OK) + except Exception as e: + Mensaje.success(data, str(e)) + return Response (data, status = status.HTTP_400_BAD_REQUEST) + + + + + + -- GitLab