Skip to content

Commit

Permalink
Merge branch 'master' into pre-commit
Browse files Browse the repository at this point in the history
  • Loading branch information
eduzen authored Jan 16, 2025
2 parents a63a391 + 79aad14 commit 1856f42
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 21 deletions.
50 changes: 50 additions & 0 deletions events/tests/test_view_report_event.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from django.core import mail
from django.urls import reverse
from django.test import TestCase, Client

from events.tests.factories import UserFactory, EventFactory


class ReportEventTest(TestCase):
def setUp(self):
self.user = UserFactory()
self.client = Client()
self.client.login(username=self.user.username, password='secret')
self.event = EventFactory()

def test_report_event_sends_email(self):
"""
Test that reporting an event sends an email to admin and redirects the user.
"""
report_url = reverse('events:report', kwargs={'event_id': self.event.id})

# Simulate reporting the event
response = self.client.post(report_url)

# ✅ Check redirection after reporting
self.assertEqual(response.status_code, 302)

# ✅ Check that an email was sent
self.assertEqual(len(mail.outbox), 1)

# ✅ Verify email details
email = mail.outbox[0]
self.assertEqual(email.subject, f'Reporte de evento: {self.event.name}')
self.assertIn(self.event.name, email.body)
self.assertIn(self.event.description, email.body)
self.assertIn('admin@python.org.ar', email.to)

def test_anonymous_user_cannot_report_event(self):
"""
Ensure that unauthenticated users cannot report an event.
"""
self.client.logout()
report_url = reverse('events:report', kwargs={'event_id': self.event.id})
response = self.client.post(report_url)

# 🔒 User should be redirected to login page
self.assertEqual(response.status_code, 302)
self.assertIn('/accounts/login/', response.url)

# 📧 No email should be sent
self.assertEqual(len(mail.outbox), 0)
6 changes: 4 additions & 2 deletions events/urls.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from django.urls import re_path
from django.urls import re_path, path
from django.views.generic.detail import DetailView

from .models import Event
Expand All @@ -12,7 +12,8 @@
EventParticipationCreate,
EventParticipationDetail,
EventParticipationDelete,
EventParticipationDownload)
EventParticipationDownload,
ReportEventView)

urlpatterns = [
re_path(r'^$', EventList.as_view(), name='events_list_all'),
Expand All @@ -33,4 +34,5 @@
name='registration'),
re_path(r'^(?P<pk>\d+)/inscripcion/(?P<participation_pk>\d+)/borrar/$',
EventParticipationDelete.as_view(), name='unregister'),
path('<int:event_id>/reportar/', ReportEventView.as_view(), name='report'),
]
57 changes: 49 additions & 8 deletions events/views.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
from braces.views import LoginRequiredMixin
from community.views import validate_obj_owner, OwnedObject
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.messages.views import SuccessMessageMixin
from django.contrib.syndication.views import Feed
from django.core.mail import send_mail
from django.http import Http404, HttpResponseRedirect
from django.shortcuts import get_object_or_404, redirect
from django.urls import reverse_lazy
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from django.urls import reverse_lazy
from django.views.generic import ListView, DetailView
from django.views.generic.edit import CreateView, UpdateView, DeleteView

from .forms import EventForm, AnonymousEventParticipationForm, AuthenticatedEventParticipationForm
from django.views import View
from django.views.generic import DetailView, ListView
from django.views.generic.edit import CreateView, DeleteView, UpdateView

from community.views import OwnedObject, validate_obj_owner

from .forms import (
AnonymousEventParticipationForm,
AuthenticatedEventParticipationForm,
EventForm,
)
from .mixins import CSVResponseMixin, EventMixin, EventParticipationMixin
from .models import Event, EventParticipation
from .mixins import EventMixin, EventParticipationMixin, CSVResponseMixin


class EventsFeed(Feed):
Expand Down Expand Up @@ -266,3 +275,35 @@ def participation_to_row(self, obj):
if self.event.has_sponsors:
row += (obj.cv, obj.share_with_sponsors)
return row


class ReportEventView(LoginRequiredMixin, View):
def post(self, request, event_id):
event = get_object_or_404(Event, pk=event_id)
try:
message = (
f"El evento '{event.name}' ha sido reportado por el usuario "
f"{request.user.username}. \n\n"
f"Detalles del evento:\n"
f"Nombre: {event.name}\n"
f"Descripción: {event.description}\n"
f"Lugar: {event.place}\n"
f"Fecha y hora: {event.start_at}\n\n"
f"Ver más detalles: {request.build_absolute_uri(event.get_absolute_url())}"
)
# Send email to admin
send_mail(
subject=f"Reporte de evento: {event.name}",
message=message,
from_email="noreply@python.org.ar",
recipient_list=["admin@python.org.ar"],
fail_silently=False,
)

txt = "El evento ha sido reportado correctamente. Gracias por tu colaboración."
messages.success(request, txt)
return redirect(reverse_lazy("events:events_list_all"))
except Exception:
txt = "Ocurrió un error al reportar el evento. Por favor, intentá nuevamente."
messages.error(request, txt)
return redirect(reverse_lazy("events:events_list_all"))
15 changes: 11 additions & 4 deletions pycompanies/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ def test_company_admin_should_have_no_matching_company_in_context(logged_client)
@pytest.mark.django_db
def test_company_disassociate_last_user_from_company(logged_client, user):
"""
Message in context should notice if is the last user associated to the company
Verifies that the message is correct and the profile is deleted when disassociating
"""
DISASSOCIATE_MESSAGE = ('Esta es la última persona vinculada a esta empresa '
'¿Estás seguro que deseas desvincularla?')
Expand All @@ -206,11 +206,18 @@ def test_company_disassociate_last_user_from_company(logged_client, user):
COMPANY_DISSASOCIATE_URL = reverse('companies:disassociate',
kwargs={'pk': user_company_profile.id})

response = logged_client.get(COMPANY_DISSASOCIATE_URL, data={'empresa': company_1})

assert 200 == response.status_code
# Simula la carga de la página de confirmación
response = logged_client.get(COMPANY_DISSASOCIATE_URL)
assert response.status_code == 200
assert DISASSOCIATE_MESSAGE == response.context_data['message']

# Simula la acción de desasociarse (esto es lo que realmente elimina el perfil)
response = logged_client.post(COMPANY_DISSASOCIATE_URL)

# Verifica redirección después de desasociarse
assert response.status_code == 302 # Redirección exitosa
assert not UserCompanyProfile.objects.filter(id=user_company_profile.id).exists()


@pytest.mark.django_db
def test_company_disassociate_one_user_from_company(logged_client, user):
Expand Down
25 changes: 18 additions & 7 deletions templates/companies/_user_actions.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,25 @@
</div>
</div>

<div class="list-group-item">
<a href="{% url 'joboffers:admin' %}" class="btn btn-default">
{% trans 'Administrar Ofertas' %}
</a>
<a href="{% url 'companies:analytics' own_company.id %}" class="btn btn-dark-green">
{% trans 'Analítica de Ofertas' %}
</a>
<div class="list-group-item text-center">
<div class="btn-group" role="group">
<a href="{% url 'joboffers:admin' %}" class="btn btn-default">
{% trans 'Administrar Ofertas' %}
</a>
<a href="{% url 'companies:analytics' own_company.id %}" class="btn btn-success">
{% trans 'Analítica de Ofertas' %}
</a>
</div>
<div style="margin-top: 10px;">
<form action="{% url 'companies:disassociate' user.company.first.id %}" method="post" style="display:inline;">
{% csrf_token %}
<button type="submit" class="btn btn-danger">
{% trans 'Desasociarse' %}
</button>
</form>
</div>
</div>

{% else %}
<div class="list-group-item">
<div class="h4 list-group-item-heading flex-center">
Expand Down
10 changes: 10 additions & 0 deletions templates/events/event_list.html
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,19 @@ <h4 class="list-group-item-heading">
{{ event.start_at|time:"TIME_FORMAT" }}
</small>
</h4>

<p class="list-group-item-text">
{{ event.description|truncatewords:"100"|striptags|safe }}
<hr>
<!-- 🚨 Report Button -->
{% if user.is_authenticated %}
<form action="{% url 'events:report' event.id %}" method="post" style="display:inline;">
{% csrf_token %}
<button type="submit" class="btn btn-danger btn-sm">
{% trans "Reportar Evento" %}
</button>
</form>
{% endif %}
</p>
</article>
{% empty %}
Expand Down

0 comments on commit 1856f42

Please sign in to comment.