From a661b30b1241c71c3910707b967757faa793b48d Mon Sep 17 00:00:00 2001 From: Bo Lopker Date: Mon, 5 Aug 2024 16:56:16 -0700 Subject: [PATCH] Don't auto attend people --- totem/circles/actions.py | 12 +-- totem/circles/models.py | 6 +- totem/circles/tests/test_views.py | 163 +++++++++++++++--------------- totem/circles/views.py | 66 ++++++------ totem/email/emails.py | 2 +- totem/email/tests.py | 20 ++++ 6 files changed, 142 insertions(+), 127 deletions(-) diff --git a/totem/circles/actions.py b/totem/circles/actions.py index 747f4f3c..2cf3a46a 100644 --- a/totem/circles/actions.py +++ b/totem/circles/actions.py @@ -28,12 +28,12 @@ def get_url(self) -> str: return reverse("circles:join", kwargs={"event_slug": self.parameters["event_slug"]}) -class AttendCircleParameters(TypedDict): - event_slug: str +# class AttendCircleParameters(TypedDict): +# event_slug: str -class AttendCircleAction(ActionBase[AttendCircleParameters]): - action_id = "circles:event_detail" +# class AttendCircleAction(ActionBase[AttendCircleParameters]): +# action_id = "circles:event_detail" - def get_url(self) -> str: - return reverse("circles:event_detail", kwargs={"event_slug": self.parameters["event_slug"]}) +# def get_url(self) -> str: +# return reverse("circles:event_detail", kwargs={"event_slug": self.parameters["event_slug"]}) diff --git a/totem/circles/models.py b/totem/circles/models.py index 2eb6d495..14a5148d 100644 --- a/totem/circles/models.py +++ b/totem/circles/models.py @@ -27,7 +27,7 @@ from totem.utils.slack import notify_slack from totem.utils.utils import full_url -from .actions import AttendCircleAction, JoinCircleAction, SubscribeAction +from .actions import JoinCircleAction, SubscribeAction from .calendar import calendar if TYPE_CHECKING: @@ -295,8 +295,8 @@ def password(self): def join_url(self, user): return JoinCircleAction(user=user, parameters={"event_slug": self.slug}).build_url() - def attend_url(self, user): - return AttendCircleAction(user=user, parameters={"event_slug": self.slug}).build_url() + # def attend_url(self, user): + # return AttendCircleAction(user=user, parameters={"event_slug": self.slug}).build_url() def __str__(self): return f"CircleEvent: {self.start}" diff --git a/totem/circles/tests/test_views.py b/totem/circles/tests/test_views.py index a0b4a6dd..76c61979 100644 --- a/totem/circles/tests/test_views.py +++ b/totem/circles/tests/test_views.py @@ -8,8 +8,7 @@ from totem.users.tests.factories import UserFactory -from ..actions import AttendCircleAction, JoinCircleAction -from ..views import AUTO_RSVP_SESSION_KEY +from ..actions import JoinCircleAction from .factories import CircleEventFactory, CircleFactory @@ -64,10 +63,6 @@ def test_event_logged_in(self, client, db): url = reverse("circles:event_detail", kwargs={"event_slug": event.slug}) response = client.get(url) assert response.status_code == 200 - # expect_words = ["Attend", "spots left", "Subscribe"] - # content = response.content.decode() - # for word in expect_words: - # assert word in content def test_event(self, client, db): event = CircleEventFactory() @@ -87,66 +82,66 @@ def test_event_no_attendee_unauth(self, client, db): response = client.get(url) assert response.status_code == 200 - def test_event_with_token(self, client, db): - event = CircleEventFactory() - user = UserFactory() - user.save() - url = AttendCircleAction(user=user, parameters={"event_slug": event.slug}).build_url() - response = client.get(url) - assert response.status_code == 200 - assert user in event.attendees.all() - assert "successfully reserved" in list(get_messages(response.wsgi_request))[0].message - - def test_event_with_token_wrong_user(self, client, db): - event = CircleEventFactory() - user = UserFactory() - user.save() - client.force_login(user) - user2 = UserFactory() - user2.save() - url = AttendCircleAction(user=user2, parameters={"event_slug": event.slug}).build_url() - response = client.get(url) - assert response.status_code == 200 - assert user not in event.attendees.all() - assert user2 not in event.attendees.all() - - def test_event_with_token_user_already_attending(self, client, db): - event = CircleEventFactory() - user = UserFactory() - user.save() - event.add_attendee(user) - url = AttendCircleAction(user=user, parameters={"event_slug": event.slug}).build_url() - response = client.get(url) - assert response.status_code == 200 - assert user in event.attendees.all() - assert list(get_messages(response.wsgi_request))[0].message == "You are already attending this session" - - def test_event_with_token_wrong_event(self, client, db): - event = CircleEventFactory() - user = UserFactory() - user.save() - url = AttendCircleAction(user=user, parameters={"event_slug": "wrong"}).build_url() - token = url.split("=")[-1] - bad_url = event.get_absolute_url() + f"?token={token}" - response = client.get(bad_url) - assert response.status_code == 200 - assert user not in event.attendees.all() - assert "Invalid or expired link" in list(get_messages(response.wsgi_request))[0].message - - def test_auto_rsvp_already_going(self, client, db): - event = CircleEventFactory() - user = UserFactory() - user.save() - event.add_attendee(user) - event.save() - client.force_login(user) - session = client.session - session[AUTO_RSVP_SESSION_KEY] = event.slug - session.save() - response = client.get(reverse("circles:event_detail", kwargs={"event_slug": event.slug})) - assert response.status_code == 200 - assert user in event.attendees.all() - assert list(get_messages(response.wsgi_request))[0].message == "You are already attending this session" + # def test_event_with_token(self, client, db): + # event = CircleEventFactory() + # user = UserFactory() + # user.save() + # url = AttendCircleAction(user=user, parameters={"event_slug": event.slug}).build_url() + # response = client.get(url) + # assert response.status_code == 200 + # assert user in event.attendees.all() + # assert "successfully reserved" in list(get_messages(response.wsgi_request))[0].message + + # def test_event_with_token_wrong_user(self, client, db): + # event = CircleEventFactory() + # user = UserFactory() + # user.save() + # client.force_login(user) + # user2 = UserFactory() + # user2.save() + # url = AttendCircleAction(user=user2, parameters={"event_slug": event.slug}).build_url() + # response = client.get(url) + # assert response.status_code == 200 + # assert user not in event.attendees.all() + # assert user2 not in event.attendees.all() + + # def test_event_with_token_user_already_attending(self, client, db): + # event = CircleEventFactory() + # user = UserFactory() + # user.save() + # event.add_attendee(user) + # url = AttendCircleAction(user=user, parameters={"event_slug": event.slug}).build_url() + # response = client.get(url) + # assert response.status_code == 200 + # assert user in event.attendees.all() + # assert list(get_messages(response.wsgi_request))[0].message == "You are already attending this session" + + # def test_event_with_token_wrong_event(self, client, db): + # event = CircleEventFactory() + # user = UserFactory() + # user.save() + # url = AttendCircleAction(user=user, parameters={"event_slug": "wrong"}).build_url() + # token = url.split("=")[-1] + # bad_url = event.get_absolute_url() + f"?token={token}" + # response = client.get(bad_url) + # assert response.status_code == 200 + # assert user not in event.attendees.all() + # assert "Invalid or expired link" in list(get_messages(response.wsgi_request))[0].message + + # def test_auto_rsvp_already_going(self, client, db): + # event = CircleEventFactory() + # user = UserFactory() + # user.save() + # event.add_attendee(user) + # event.save() + # client.force_login(user) + # session = client.session + # session[AUTO_RSVP_SESSION_KEY] = event.slug + # session.save() + # response = client.get(reverse("circles:event_detail", kwargs={"event_slug": event.slug})) + # assert response.status_code == 200 + # assert user in event.attendees.all() + # assert list(get_messages(response.wsgi_request))[0].message == "You are already attending this session" class TestJoinView: @@ -329,24 +324,24 @@ def test_rsvp_attending_late(self, client, db): assert user not in event.joined.all() assert user not in event.attendees.all() - def test_rsvp_auto_rsvp(self, client, db): - """Test auto rsvp when user is not logged in, but then makes an account and goes back to the event page.""" - event = CircleEventFactory() - response = client.post(reverse("circles:rsvp", kwargs={"event_slug": event.slug}), data={"action": "yes"}) - assert response.status_code == 302 - assert "signup" in response.url - assert event.slug in response.url - session = client.session - assert session[AUTO_RSVP_SESSION_KEY] == event.slug - user = UserFactory() - user.save() - client.force_login(user) - response = client.get(reverse("circles:event_detail", kwargs={"event_slug": event.slug})) - assert response.status_code == 200 - assert user in event.attendees.all() - message = list(get_messages(response.wsgi_request)) - assert "spot" in message[0].message.lower() - assert client.session.get(AUTO_RSVP_SESSION_KEY) is None + # def test_rsvp_auto_rsvp(self, client, db): + # """Test auto rsvp when user is not logged in, but then makes an account and goes back to the event page.""" + # event = CircleEventFactory() + # response = client.post(reverse("circles:rsvp", kwargs={"event_slug": event.slug}), data={"action": "yes"}) + # assert response.status_code == 302 + # assert "signup" in response.url + # assert event.slug in response.url + # session = client.session + # assert session[AUTO_RSVP_SESSION_KEY] == event.slug + # user = UserFactory() + # user.save() + # client.force_login(user) + # response = client.get(reverse("circles:event_detail", kwargs={"event_slug": event.slug})) + # assert response.status_code == 200 + # assert user in event.attendees.all() + # message = list(get_messages(response.wsgi_request)) + # assert "spot" in message[0].message.lower() + # assert client.session.get(AUTO_RSVP_SESSION_KEY) is None def test_attending_email_sent(self, client, db): # test that send_notify_circle_signup is called when user RSVPs diff --git a/totem/circles/views.py b/totem/circles/views.py index e4f74ef2..8b4ae61e 100644 --- a/totem/circles/views.py +++ b/totem/circles/views.py @@ -12,7 +12,7 @@ from totem.utils.hash import basic_hash from totem.utils.utils import is_ajax -from .actions import AttendCircleAction, JoinCircleAction, SubscribeAction +from .actions import JoinCircleAction, SubscribeAction from .filters import ( all_upcoming_recommended_circles, upcoming_events_by_author, @@ -53,19 +53,19 @@ def _circle_detail(request: HttpRequest, user: User, circle: Circle, event: Circ if not circle.published and not user.is_staff: raise PermissionDenied - if user.is_authenticated and request.session.get(AUTO_RSVP_SESSION_KEY) and event: - event_slug = request.session[AUTO_RSVP_SESSION_KEY] - del request.session[AUTO_RSVP_SESSION_KEY] - if event_slug == event.slug: - try: - _add_or_remove_attendee(user, event, True) - messages.info(request, "Your spot in this Circle has been reserved.") - except CircleEventException as e: - messages.error(request, str(e)) + # if user.is_authenticated and request.session.get(AUTO_RSVP_SESSION_KEY) and event: + # event_slug = request.session[AUTO_RSVP_SESSION_KEY] + # del request.session[AUTO_RSVP_SESSION_KEY] + # if event_slug == event.slug: + # try: + # _add_or_remove_attendee(user, event, True) + # messages.info(request, "Your spot in this Circle has been reserved.") + # except CircleEventException as e: + # messages.error(request, str(e)) - token = request.GET.get("token") - if token and event: - _resolve_event_action(request, user, event, token) + # token = request.GET.get("token") + # if token and event: + # _resolve_event_action(request, user, event, token) attending = False joinable = False @@ -92,26 +92,26 @@ def _circle_detail(request: HttpRequest, user: User, circle: Circle, event: Circ ) -def _resolve_event_action(request: HttpRequest, user: User, event: CircleEvent, token: str): - try: - token_user, params = AttendCircleAction.resolve(token) - if user.is_authenticated and user != token_user: - return - token_event_slug = params["event_slug"] - if token_event_slug != event.slug: - print("Invalid event slug") - raise PermissionDenied - try: - event.add_attendee(token_user) - except CircleEventException as e: - messages.error(request, f"{str(e)}") - return - messages.success(request, "You have successfully reserved a spot to this session.") - except Exception as e: - capture_exception(e) - messages.error( - request, "Invalid or expired link. If you think this is an error, please contact us: help@totem.org." - ) +# def _resolve_event_action(request: HttpRequest, user: User, event: CircleEvent, token: str): +# try: +# token_user, params = AttendCircleAction.resolve(token) +# if user.is_authenticated and user != token_user: +# return +# token_event_slug = params["event_slug"] +# if token_event_slug != event.slug: +# print("Invalid event slug") +# raise PermissionDenied +# try: +# event.add_attendee(token_user) +# except CircleEventException as e: +# messages.error(request, f"{str(e)}") +# return +# messages.success(request, "You have successfully reserved a spot to this session.") +# except Exception as e: +# capture_exception(e) +# messages.error( +# request, "Invalid or expired link. If you think this is an error, please contact us: help@totem.org." +# ) def ics_hash(slug, user_ics_key): diff --git a/totem/email/emails.py b/totem/email/emails.py index 1063708a..ef332f19 100644 --- a/totem/email/emails.py +++ b/totem/email/emails.py @@ -196,7 +196,7 @@ def send_notify_circle_advertisement(event: CircleEvent, user: User): start = to_human_time(user, event.start) CircleAdvertisementEmail( recipient=user.email, - link=event.attend_url(user), # type: ignore + link=make_email_url(event.get_absolute_url()), # type: ignore start=start, event_title=event.circle.title, unsubscribe_url=event.circle.subscribe_url(user, subscribe=False), # type: ignore diff --git a/totem/email/tests.py b/totem/email/tests.py index 22e7c96e..1e9a6763 100644 --- a/totem/email/tests.py +++ b/totem/email/tests.py @@ -1,6 +1,9 @@ +from django.core import mail from django.test import Client, override_settings from django.urls import reverse +from totem.circles.tests.factories import CircleEventFactory +from totem.email.emails import send_notify_circle_advertisement from totem.users.tests.factories import UserFactory from .views import get_templates @@ -39,3 +42,20 @@ def test_template_list_staff(self, client: Client, db): client.force_login(user) response = client.get(reverse("email:template")) assert response.status_code == 200 + + +class TestAdvertEmail: + def test_advert_email(self, client, db): + user = UserFactory() + user.save() + event = CircleEventFactory() + event.save() + send_notify_circle_advertisement(event, user) + assert len(mail.outbox) == 1 + email = mail.outbox[0] + assert email.to == [user.email] + message = str(email.message()) + assert "http://testserver/circles/event" in message + assert event.circle.title in message + assert "http://testserver/circles/subscribe" in message + assert event.circle.slug in message