Skip to content

Commit

Permalink
Add more checks to vacations, and now vacations send mails
Browse files Browse the repository at this point in the history
  • Loading branch information
Heibert committed Jul 8, 2024
1 parent 9448d24 commit 3928bfa
Show file tree
Hide file tree
Showing 8 changed files with 262 additions and 39 deletions.
54 changes: 45 additions & 9 deletions INSIGHTSAPI/INSIGHTSAPI/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from django.core.mail import get_connection
from django.test import override_settings
from django.core.mail import EmailMessage
from django.core.mail import send_mail
from django.urls import reverse
from INSIGHTSAPI.tasks import add_numbers

Expand All @@ -29,18 +30,17 @@ def test_add_numbers_task(self):
self.assertEqual(task_result, 7)


@override_settings(
EMAIL_BACKEND="INSIGHTSAPI.custom.custom_email_backend.CustomEmailBackend",
)
class CustomEmailBackendTestCase(TestCase):
"""Test case for the CustomEmailBackend class."""

@override_settings(
EMAIL_BACKEND="INSIGHTSAPI.custom.custom_email_backend.CustomEmailBackend",
)
def test_send_messages(self):
"""Test the send_messages method."""
# By default in a test environment, the email is not sent
backend = get_connection()
email = EmailMessage(
"Subject here",
"Send mail class",
"Here is the message.",
None,
[settings.EMAIL_FOR_TEST],
Expand All @@ -51,15 +51,13 @@ def test_send_messages(self):

def test_send_messages_to_wrong_email(self):
"""Test the send_messages method."""
# By default in a test environment, the email is not sent
backend = "INSIGHTSAPI.custom.custom_email_backend.CustomEmailBackend"
try:
email = EmailMessage(
"Subject here",
"Here is the message.",
None,
["not_allowed_email@not_allowed.com"],
connection=get_connection(backend=backend),
connection=get_connection(),
)
email.send()
self.fail("Email should not be sent.")
Expand All @@ -69,11 +67,49 @@ def test_send_messages_to_wrong_email(self):
@override_settings(
ADMINS=[("Heibert Mogollon", settings.EMAIL_FOR_TEST)],
DEBUG=False, # Ensure DEBUG is False to enable email sending on errors
EMAIL_BACKEND="INSIGHTSAPI.custom.custom_email_backend.CustomEmailBackend",
)
def test_admin_email_on_server_error(self):
"""Test that an email is sent to the admins on a server error."""
with self.assertRaises(Exception) as context:
self.client.get(reverse("trigger_error"))

self.assertIn("Test error", str(context.exception))

def test_send_html_mail(self):
"""Test the send_html_mail method."""
backend = get_connection()
email = EmailMessage(
"HTML Email class",
"Here is the message.",
None,
[settings.EMAIL_FOR_TEST],
connection=backend,
)
email.content_subtype = "html"
email.send()
self.assertEqual(len(backend.outbox), 1)

def test_send_mail(self):
"""Test the send_mail method."""
backend = get_connection()
send_mail(
"Send mail test",
"Here is the message.",
None,
[settings.EMAIL_FOR_TEST],
connection=backend,
)
self.assertEqual(len(backend.outbox), 1)

def test_send_mail_html(self):
"""Test the send_mail method."""
backend = get_connection()
send_mail(
"HTML Send mail test",
"Here is the message.",
None,
[settings.EMAIL_FOR_TEST],
html_message="<h1>HTML message</h1>",
connection=backend,
)
self.assertEqual(len(backend.outbox), 1)
4 changes: 2 additions & 2 deletions INSIGHTSAPI/employment_management/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,9 @@ def test_list_employment_certifications(self):
self.assertEqual(len(response.data), EmploymentCertification.objects.count())
self.assertEqual(response.data[0]["cedula"], self.user.cedula)
self.assertEqual(response.data[0]["position"], self.payslip_data["job_title"])
self.assertEqual(response.data[0]["salary"], str(self.payslip_data["salary"]))
self.assertEqual(response.data[0]["salary"], str(self.payslip_data["salary"]) + ".00")
self.assertEqual(
response.data[0]["bonuses"], str(self.payslip_data["bonus_paycheck"])
response.data[0]["bonuses"], str(self.payslip_data["bonus_paycheck"]) + ".00"
)
self.assertEqual(response.data[0]["contract_type"], "Contrato de trabajo")
self.assertEqual(response.data[0]["expedition_city"], "Bogotá")
3 changes: 2 additions & 1 deletion INSIGHTSAPI/goals/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# from media.goals_templates.goals_delivery import get_template
from .models import Goals, TableInfo


# * Recuerda que cuando corres los tests, NO se envía un correo electrónico real.
class GoalAPITestCase(BaseTestCase):
"""Test the Goal API."""

Expand Down Expand Up @@ -434,6 +434,7 @@ def test_patch_goal_delivery_claro(self):
response.data["message"], "La meta fue aceptada.", response.data
)


def test_patch_goal_execution(self):
"""Test the update-goal view."""
# Get the first goal from the database
Expand Down
6 changes: 5 additions & 1 deletion INSIGHTSAPI/goals/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from rest_framework import viewsets
from rest_framework.response import Response
from django.core.mail import send_mail
from django.core.mail import get_connection

from services.permissions import CustomizableGetDjangoModelViewPermissions

Expand Down Expand Up @@ -68,6 +69,7 @@ def partial_update(self, request, *args, **kwargs):
"""
table_data_plain += f"{table.fringe:<15} | {table.diary_goal:<10} | {table.days:<4} | {table.month_goal:<18} | {table.hours:<7} | {table.collection_account}\n"
if "CLARO" in instance.campaign_goal.upper():
backend = get_connection()
send_mail(
f"Meta {month}",
f"""
Expand All @@ -88,7 +90,7 @@ def partial_update(self, request, *args, **kwargs):
""",
None,
[user.email],
html_message="""
html_message=f"""
<p style="text-align: start">
La meta fue <b>{accepted_state}</b>.<br>
Expand Down Expand Up @@ -116,7 +118,9 @@ def partial_update(self, request, *args, **kwargs):
</tr>
</table>
""",
connection=backend,
)
print("correo enviado")
return Response(
{"message": f"La meta fue {accepted_state}."},
status=framework_status.HTTP_200_OK,
Expand Down
65 changes: 57 additions & 8 deletions INSIGHTSAPI/vacation/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""This module contains the model for the vacation request """

from django.db import models
from django.core.mail import send_mail
from users.models import User
from notifications.utils import create_notification
from django.utils import timezone
Expand All @@ -26,7 +27,7 @@ class VacationRequest(models.Model):
("PENDIENTE", "PENDIENTE"),
("APROBADA", "APROBADA"),
("RECHAZADA", "RECHAZADA"),
("CANCELADA", "CANCELADA"),
# ("CANCELADA", "CANCELADA"),
],
max_length=100,
default="PENDIENTE",
Expand Down Expand Up @@ -75,17 +76,65 @@ def save(self, *args, **kwargs):
f"Tus vacaciones del {self.start_date} al {self.end_date} han sido aprobadas. Esperamos que las disfrutes ⛱!.",
self.user,
)
message = f"""
Hola {self.user.get_full_name()} 👋,
Nos complace informarte que tu solicitud de vacaciones del {self.start_date.strftime("%d de %B del %Y")} al {self.end_date.strftime("%d de %B del %Y")} ha sido aprobada.
Esperamos que disfrutes de este merecido descanso y que regreses con energías renovadas. Si necesitas alguna información adicional o asistencia durante tus vacaciones, no dudes en contactarnos.
¡Te deseamos unas vacaciones maravillosas y relajantes! ⛱
Saludos cordiales,
"""
send_mail(
"Vacaciones aprobadas",
message,
None,
[str(self.user.email)],
)
elif self.status == "RECHAZADA":
message = f"""
Hola {self.user.get_full_name()} 👋,
Lamentamos informarte que tu solicitud de vacaciones del {self.start_date.strftime("%d de %B del %Y")} al {self.end_date.strftime("%d de %B del %Y")} ha sido rechazada.
Nos vimos en la necesidad de tomar esta difícil decisión debido a: {self.comment}.
Habla con tu gerente o con el departamento de Recursos Humanos si tienes alguna pregunta o necesitas más información. Recuerda que puedes volver a enviar tu solicitud en otro momento.
Saludos cordiales,
"""
send_mail(
"Estado de tu solicitud de vacaciones",
message,
None,
[str(self.user.email)],
)
create_notification(
f"Solicitud de vacaciones rechazada",
f"Tu solicitud de vacaciones del {self.start_date} al {self.end_date} ha sido rechazada.",
self.user,
)
elif self.status == "CANCELADA":
create_notification(
f"Solicitud de vacaciones cancelada",
f"Tu solicitud de vacaciones del {self.start_date} al {self.end_date} ha sido cancelada.",
self.user,
)
super().save(*args, **kwargs)
# elif self.status == "CANCELADA":
# message = f"""
# Hola {self.user.get_full_name()} 👋,

# Hemos recibido tu solicitud de cancelación de vacaciones del {self.start_date.strftime("%d de %B del %Y")} al {self.end_date.strftime("%d de %B del %Y")}.

# Si tienes alguna pregunta o necesitas más información, no dudes en contactarnos.

# Saludos cordiales,
# """
# send_mail(
# "Solicitud de cancelación de vacaciones",
# message,
# None,
# [str(self.user.email)],
# )
# create_notification(
# f"Solicitud de vacaciones cancelada",
# f"Tu solicitud de vacaciones del {self.start_date} al {self.end_date} ha sido cancelada.",
# self.user,
# )
super().save(*args, **kwargs)
13 changes: 13 additions & 0 deletions INSIGHTSAPI/vacation/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,28 @@ def validate(self, attrs):
"""Validate the dates of the vacation request."""
# Check if is a creation or an update
if not self.instance:
# Creation
created_at = datetime.datetime.now()
if created_at.day >= 20:
raise serializers.ValidationError(
"No puedes solicitar vacaciones después del día 20."
)
if (
attrs["start_date"].month == created_at.month
and attrs["start_date"].year == created_at.year
):
raise serializers.ValidationError(
"No puedes solicitar vacaciones para el mes actual."
)

if attrs["start_date"] > attrs["end_date"]:
raise serializers.ValidationError(
"La fecha de inicio no puede ser mayor a la fecha de fin."
)
if (attrs["end_date"] - attrs["start_date"]).days > 30:
raise serializers.ValidationError(
"Tu solicitud no puede ser mayor a 30 días."
)
uploaded_by = (
self.instance.uploaded_by
if self.instance
Expand Down
38 changes: 27 additions & 11 deletions INSIGHTSAPI/vacation/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,22 @@ def test_vacation_create(self):
self.assertEqual(response.status_code, status.HTTP_201_CREATED, response.data)
self.assertEqual(response.data["hr_approbation"], None)

def test_vacation_create_same_month(self):
"""Test creating a vacation that spans two months."""
self.vacation_request["start_date"] = "2024-07-01"
self.vacation_request["end_date"] = "2024-07-25"
response = self.client.post(
reverse("vacation-list"),
self.vacation_request,
)
self.assertEqual(
response.status_code, status.HTTP_400_BAD_REQUEST, response.data
)
self.assertEqual(
response.data["non_field_errors"][0],
"No puedes solicitar vacaciones para el mes actual.",
)

def test_vacation_list_user(self):
"""Test listing all vacations endpoint for a user."""
self.vacation_request["user"] = self.test_user
Expand Down Expand Up @@ -165,17 +181,17 @@ def test_vacation_create_invalid_user(self):
response.data,
)

def test_vacation_owner_cancel(self):
"""Test the owner cancelling a vacation."""
self.vacation_request["user"] = self.test_user
self.vacation_request["uploaded_by"] = self.user
vacation_object = VacationRequest.objects.create(**self.vacation_request)
response = self.client.patch(
reverse("vacation-detail", kwargs={"pk": vacation_object.pk}),
{"status": "CANCELADA"},
)
self.assertEqual(response.status_code, status.HTTP_200_OK, response.data)
self.assertEqual(response.data["status"], "CANCELADA")
# def test_vacation_owner_cancel(self):
# """Test the owner cancelling a vacation."""
# self.vacation_request["user"] = self.test_user
# self.vacation_request["uploaded_by"] = self.user
# vacation_object = VacationRequest.objects.create(**self.vacation_request)
# response = self.client.patch(
# reverse("vacation-detail", kwargs={"pk": vacation_object.pk}),
# {"status": "CANCELADA"},
# )
# self.assertEqual(response.status_code, status.HTTP_200_OK, response.data)
# self.assertEqual(response.data["status"], "CANCELADA")

def test_vacation_owner_cancel_no_owner(self):
"""Test the owner cancelling a vacation without being the owner."""
Expand Down
Loading

0 comments on commit 3928bfa

Please sign in to comment.