From e028f6dcede671c5590c75803bc0d1be3a43daca Mon Sep 17 00:00:00 2001 From: Caio Date: Thu, 7 Dec 2023 22:27:43 -0300 Subject: [PATCH 1/7] models(schedules): add created_at field --- api/api/models.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api/api/models.py b/api/api/models.py index 84d8f86..4a891cb 100644 --- a/api/api/models.py +++ b/api/api/models.py @@ -2,7 +2,7 @@ from unidecode import unidecode from django.contrib.postgres.fields import ArrayField from users.models import User - +from django.utils import timezone class Department(models.Model): """Classe que representa um departamento. @@ -76,6 +76,7 @@ class Schedule(models.Model): user = models.ForeignKey( User, on_delete=models.CASCADE, related_name='schedules') classes = models.JSONField(default=list) + created_at = models.DateTimeField(default=timezone.now) def __str__(self): return f'Class: {self.id} - User: {self.user.email}' From 9b754ced794c0eb9965ca4b22e85d7d1cbd71bf4 Mon Sep 17 00:00:00 2001 From: Caio Date: Thu, 7 Dec 2023 22:27:59 -0300 Subject: [PATCH 2/7] serializers(schedules): add serializer for schedule --- api/api/serializers.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/api/api/serializers.py b/api/api/serializers.py index c7f9a5b..d08db8b 100644 --- a/api/api/serializers.py +++ b/api/api/serializers.py @@ -1,5 +1,5 @@ from rest_framework.serializers import ModelSerializer -from api.models import Department, Discipline, Class +from api.models import Department, Discipline, Class, Schedule class DepartmentSerializer(ModelSerializer): @@ -28,3 +28,8 @@ class DisciplineSerializer(DisciplineSerializerSchedule): class ClassSerializerSchedule(ClassSerializer): discipline = DisciplineSerializerSchedule() + +class ScheduleSerializer(ModelSerializer): + class Meta: + model = Schedule + exclude = ['user'] From 67ed0ee9b26d29fb2d939cc2838fa49f3657871b Mon Sep 17 00:00:00 2001 From: Caio Date: Thu, 7 Dec 2023 22:28:20 -0300 Subject: [PATCH 3/7] api(urls): add get_schedules endpoint --- api/api/urls.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/api/api/urls.py b/api/api/urls.py index 4625065..fb644d8 100644 --- a/api/api/urls.py +++ b/api/api/urls.py @@ -1,5 +1,5 @@ from django.urls import path -from api.views import save_schedule, views +from api.views import save_schedule, get_schedules, views app_name = 'api' @@ -7,5 +7,6 @@ path('', views.Search.as_view(), name="search"), path('year-period/', views.YearPeriod.as_view(), name="year-period"), path('schedule/save/', save_schedule.SaveSchedule.as_view(), name="save-schedule"), - path('schedule/', views.Schedule.as_view(), name="schedule") + path('schedule/', views.Schedule.as_view(), name="schedule"), + path('schedules/', get_schedules.GetSchedules.as_view(), name="get-schedules") ] From 492c0decc22322b768a27c649ae2820b4ef4a672 Mon Sep 17 00:00:00 2001 From: Caio Date: Thu, 7 Dec 2023 22:33:38 -0300 Subject: [PATCH 4/7] models(migrations): make migrations --- .../migrations/0008_schedule_created_at.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 api/api/migrations/0008_schedule_created_at.py diff --git a/api/api/migrations/0008_schedule_created_at.py b/api/api/migrations/0008_schedule_created_at.py new file mode 100644 index 0000000..6bceff2 --- /dev/null +++ b/api/api/migrations/0008_schedule_created_at.py @@ -0,0 +1,19 @@ +# Generated by Django 4.2.5 on 2023-12-08 01:10 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0007_schedule'), + ] + + operations = [ + migrations.AddField( + model_name='schedule', + name='created_at', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + ] From d4b15057a8736328d45ab2601a55cd85946ad2b0 Mon Sep 17 00:00:00 2001 From: Caio Date: Thu, 7 Dec 2023 22:33:57 -0300 Subject: [PATCH 5/7] api(schedules): add get schedules api --- api/api/views/get_schedules.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 api/api/views/get_schedules.py diff --git a/api/api/views/get_schedules.py b/api/api/views/get_schedules.py new file mode 100644 index 0000000..08cd0df --- /dev/null +++ b/api/api/views/get_schedules.py @@ -0,0 +1,32 @@ +from drf_yasg.utils import swagger_auto_schema +from drf_yasg import openapi + +from rest_framework.views import APIView +from rest_framework.permissions import IsAuthenticated +from rest_framework import status, request, response + +from api.swagger import Errors +from api.serializers import ScheduleSerializer + +from utils.db_handler import get_schedules + +class GetSchedules(APIView): + + permission_classes = [IsAuthenticated] + + @swagger_auto_schema( + operation_description="Retorna as grades horárias do usuário logado.", + security=[{'Bearer': []}], + responses={ + 200: openapi.Response('OK', ScheduleSerializer(many=True)), + **Errors([401, 403]).retrieve_erros() + } + ) + def get(self, request: request.Request) -> response.Response: + """Retorna as grades horárias do usuário logado.""" + + user = request.user + schedules = get_schedules(user) + data = ScheduleSerializer(schedules, many=True).data + + return response.Response(status=status.HTTP_200_OK, data=data) \ No newline at end of file From fe4dee55eb356d98933344e5a4d7c19b6424fc8c Mon Sep 17 00:00:00 2001 From: Caio Date: Thu, 7 Dec 2023 22:34:30 -0300 Subject: [PATCH 6/7] utils(db_handler): add get_schedule function --- api/utils/db_handler.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/api/utils/db_handler.py b/api/utils/db_handler.py index d59e287..f6ec7b5 100644 --- a/api/utils/db_handler.py +++ b/api/utils/db_handler.py @@ -90,3 +90,7 @@ def save_schedule(user: User, schedule_to_save: list[Class]) -> bool: return False return True + +def get_schedules(user: User) -> QuerySet: + """Retorna as grades horárias de um usuário.""" + return Schedule.objects.filter(user=user).all() From 610c520530642e2ddad59d29ed3ab03e33fcc719 Mon Sep 17 00:00:00 2001 From: Caio Date: Thu, 7 Dec 2023 23:14:08 -0300 Subject: [PATCH 7/7] api(test): make tests for get schedule api --- api/api/tests/test_get_schedules_api.py | 70 +++++++++++++++++++++++++ api/api/tests/test_schedule_save.py | 1 - 2 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 api/api/tests/test_get_schedules_api.py diff --git a/api/api/tests/test_get_schedules_api.py b/api/api/tests/test_get_schedules_api.py new file mode 100644 index 0000000..dac4974 --- /dev/null +++ b/api/api/tests/test_get_schedules_api.py @@ -0,0 +1,70 @@ +from rest_framework_simplejwt.serializers import TokenObtainPairSerializer +from rest_framework.test import APITestCase +from rest_framework.reverse import reverse + +import utils.db_handler as dbh + +from users.models import User + +import json + + +class TestGetSchedules(APITestCase): + def setUp(self): + self.department = dbh.get_or_create_department('518', '2023', '2') + self.discipline = dbh.get_or_create_discipline( + 'CÁLCULO 1', 'MAT0025', self.department) + self._class = dbh.create_class(['EDSON ALVES DA COSTA JUNIOR'], 'FGA - I8', '35T23', [ + 'Terça-feira 14:00 às 15:50', 'Quinta-feira 14:00 às 15:50'], '1', [], self.discipline) + + body = json.dumps( + { + "classes": [self._class.id] + } + ) + + self.user, _ = User.objects.get_or_create( + first_name='Aroldo', + last_name='Silva', + picture_url='https://www.photo.com', + email="aroldosilva@none.com" + ) + self.user.save() + + tokens = TokenObtainPairSerializer.get_token(self.user) + self.access_token = tokens.access_token + + self.url = reverse('api:get-schedules') + self.content_type = 'application/json' + + self.schedules = self.client.post( + reverse('api:schedule'), body, content_type=self.content_type).data + + self.schedule_json = json.dumps(self.schedules[0]) + + self.headers = { + 'Authorization': 'Bearer ' + str(self.access_token) + } + self.client.post(reverse('api:save-schedule'), + self.schedule_json, content_type=self.content_type, headers=self.headers) + + def test_get_schedules(self): + """ + Testa a obtenção de horários salvos + """ + + content = self.client.get( + self.url, headers=self.headers) + + self.assertEqual(len(content.data), 1) + self.assertEqual(content.status_code, 200) + + def test_get_schedules_with_invalid_token(self): + """ + Testa a obtenção de horários salvos com um token inválido + """ + + content = self.client.get( + self.url, headers={'Authorization': 'Bearer ' + str(self.access_token) + '1'}) + + self.assertEqual(content.status_code, 403) \ No newline at end of file diff --git a/api/api/tests/test_schedule_save.py b/api/api/tests/test_schedule_save.py index bbfe7a5..2de9f5f 100644 --- a/api/api/tests/test_schedule_save.py +++ b/api/api/tests/test_schedule_save.py @@ -152,7 +152,6 @@ def test_save_correct_schedule(self): response = self.make_post_request(schedule=schedule) - self.assertEqual(self.user.schedules.all()[0].classes, schedule) self.assertEqual(len(self.user.schedules.all()), 1) self.assertEqual(response.status_code, 201)