diff --git a/openbook_auth/schema/mutations.py b/openbook_auth/schema/mutations.py index 69daf5bd9b40a53b24b164806ba28cd7313f536a..7728ec0804c9bcfabc40e650cf80b31bfd9265d7 100644 --- a/openbook_auth/schema/mutations.py +++ b/openbook_auth/schema/mutations.py @@ -169,8 +169,11 @@ class Mutation: ) insights = insight_model.objects.order_by("-date_published")[:3] + + subscription_token = str(uuid.uuid4()) + NotificationsService.send_welcome_email_series_notification( - user=current_user, spaces=spaces, insights=insights + user=current_user, spaces=spaces, insights=insights, token=subscription_token ) updated_fields = _get_updated_fields(current_user_fields_before, current_user_fields_after) @@ -296,3 +299,9 @@ class Mutation: current_user.remove_insight_bookmark(insight_id) # To maintain compatibility with older versions UserFavorite.unfavorite(user=current_user, favoritable_id=insight_id, favoritable_type="insight") return Result(success=True) + + @strawberry.mutation() + @sync_to_async + def unsubscribe_from_newsletter(self, info, token: str) -> Result: + NotificationApi.cancel_workflow(transaction_id=token) + return Result(success=True) diff --git a/openbook_auth/tests/test_graphql.py b/openbook_auth/tests/test_graphql.py index df86032a0a14a9009083598f67788808c802ddde..d479cdb6d716ebd5c83cdbd7114f0f3d2e55c052 100644 --- a/openbook_auth/tests/test_graphql.py +++ b/openbook_auth/tests/test_graphql.py @@ -1534,3 +1534,22 @@ class TestUsers: response = get_connections_by_user_id_query(user_id=user1.id) assert_is_unauthorized(response) + + @mock.patch("openbook_notifications.api.NotificationApi.cancel_workflow") + def test_can_unsubscribe_from_newsletter(self, mock_cancel_workflow): + token = str(uuid.uuid4()) + executed = async_to_sync(schema.execute)( + """ + mutation test($token: String!) { + unsubscribeFromNewsletter(token: $token) { + success + } + } + """, + context_value=benedict({"request": {"user": AnonymousUser}}), + variable_values={"token": token}, + ) + + assert executed.errors is None + mock_cancel_workflow.assert_called_once_with(transaction_id=token) + assert executed.data["unsubscribeFromNewsletter"]["success"] is True diff --git a/openbook_communities/schema/queries.py b/openbook_communities/schema/queries.py index 96f75e76bcf4437ef6eed0efbbced40e14468903..0c9965532924a239e6fc16d364e7b951103a222f 100644 --- a/openbook_communities/schema/queries.py +++ b/openbook_communities/schema/queries.py @@ -364,7 +364,3 @@ class Query: offset, limit, ) - - @strawberry_django.field() - def get_stuff(self) -> List[SpaceUserConnectionType]: - return [SpaceUserConnectionType.MEMBER, SpaceUserConnectionType.CREATOR] diff --git a/openbook_notifications/notifications.py b/openbook_notifications/notifications.py index cafdafff30a0c1c9685dc83eb31ce559e7f82d27..64e130336bc909fcd7be42d5230ea8f704282827 100644 --- a/openbook_notifications/notifications.py +++ b/openbook_notifications/notifications.py @@ -391,10 +391,11 @@ class WelcomeEmailSeriesNotification(Notification): self, user: str, payload: WelcomeEmailSeriesPayload, + token: str, ): super().__init__( workflow=Workflow.WELCOME_EMAIL_SERIES.value, recipients=user, payload=payload.to_dict(), - transaction_id=user, # user id is used as transaction id so that we can easily unsubscribe from the email series + transaction_id=token, # token is used as transaction_id to cancel the workflow and unsubscribe the user from newsletter ) diff --git a/openbook_notifications/payloads.py b/openbook_notifications/payloads.py index 910d409b4211bef9b6fca8c0ce8eb42cd2de2ec3..528969075a1de12deda1818adffb9ee37e377dfd 100644 --- a/openbook_notifications/payloads.py +++ b/openbook_notifications/payloads.py @@ -613,12 +613,13 @@ class CommentReactionPayload(Payload): class WelcomeEmailSeriesPayload(Payload): NOTIFICATION_VERSION = "1.0.0" - def __init__(self, user: User, spaces, insights): + def __init__(self, user: User, spaces, insights, token): super().__init__( data={ "user": UserData.from_user(user).to_dict(), "recommendedSpaces": [SpaceData.from_community(space).to_dict() for space in spaces], "recommendedInsights": [InsightData.from_insight(insight).to_dict() for insight in insights], + "token": token, }, notification_type=NotificationType.WELCOME_EMAIL_SERIES.value, notification_version=WelcomeEmailSeriesPayload.NOTIFICATION_VERSION, diff --git a/openbook_notifications/services.py b/openbook_notifications/services.py index 8aa843b684c17eaf12ecf0bc6132cc73cf8de503..28c0c310055e8a6b006630196a676800553b4100 100644 --- a/openbook_notifications/services.py +++ b/openbook_notifications/services.py @@ -362,9 +362,10 @@ class NotificationsService: notification.send() @staticmethod - def send_welcome_email_series_notification(user: User, spaces, insights): + def send_welcome_email_series_notification(user: User, spaces, insights, token): notification = WelcomeEmailSeriesNotification( user=str(user.username), - payload=WelcomeEmailSeriesPayload(user=user, spaces=spaces, insights=insights), + payload=WelcomeEmailSeriesPayload(user=user, spaces=spaces, insights=insights, token=token), + token=token, ) notification.send()