Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: language event middleware #1611

Merged
merged 2 commits into from
Aug 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions benefits/core/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,12 @@ class ChangedLanguageEvent(MiddlewareMixin):

def process_view(self, request, view_func, view_args, view_kwargs):
if view_func == i18n.set_language:
new_lang = request.POST["language"]
event = analytics.ChangedLanguageEvent(request, new_lang)
analytics.send_event(event)
new_lang = request.POST.get("language")
if new_lang:
event = analytics.ChangedLanguageEvent(request, new_lang)
analytics.send_event(event)
else:
logger.warning("i18n.set_language POST without language")
return None


Expand Down
91 changes: 91 additions & 0 deletions tests/pytest/core/test_middleware_changed_language_event.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
from django.contrib.sessions.middleware import SessionMiddleware
from django.middleware.locale import LocaleMiddleware
from django.utils.decorators import decorator_from_middleware
from django.views import i18n

import benefits.core.analytics
from benefits.core.analytics import ChangedLanguageEvent as Analytics_ChangedLanguageEvent
from benefits.core.middleware import ChangedLanguageEvent as Middleware_ChangedLanguageEvent

import pytest


@pytest.fixture
def request_nolanguage(rf):
"""
Fixture creates and initializes a new Django POST request without a language parameter in the body
"""
# create a request for the path, initialize
post_request = rf.post("/some/path")

# https://stackoverflow.com/a/55530933/358804
middleware = [SessionMiddleware(lambda x: x), LocaleMiddleware(lambda x: x)]
for m in middleware:
m.process_request(post_request)

post_request.session.save()

return post_request


@pytest.fixture
def request_withlanguage(rf):
"""
Fixture creates and initializes a new Django POST request with a language parameter in the body
"""
# create a request for the path with a language parameter
post_request = rf.post("/some/path", {"language": "es"})

# https://stackoverflow.com/a/55530933/358804
middleware = [SessionMiddleware(lambda x: x), LocaleMiddleware(lambda x: x)]
for m in middleware:
m.process_request(post_request)

post_request.session.save()

return post_request


@pytest.fixture
def decorated_view_not_i18n(mocked_view):
return decorator_from_middleware(Middleware_ChangedLanguageEvent)(mocked_view)


@pytest.fixture
def decorated_view_i18n():
return decorator_from_middleware(Middleware_ChangedLanguageEvent)(i18n.set_language)


@pytest.fixture
def spy_send_event(mocker):
return mocker.spy(benefits.core.analytics, "send_event")


@pytest.mark.django_db
def test_changed_language_wrong_view_func(request_withlanguage, decorated_view_not_i18n, spy_send_event):
# we don't need the response
decorated_view_not_i18n(request_withlanguage)

# event should not have been sent
spy_send_event.assert_not_called()


@pytest.mark.django_db
def test_changed_language_no_language(request_nolanguage, decorated_view_i18n, spy_send_event):
# we don't need the response
decorated_view_i18n(request_nolanguage)

# event should not have been sent
spy_send_event.assert_not_called()


@pytest.mark.django_db
def test_changed_language_with_language(request_withlanguage, decorated_view_i18n, spy_send_event):
# we don't need the response
decorated_view_i18n(request_withlanguage)

# event should have been sent
spy_send_event.assert_called_once()
# the first arg of the first (and only) call
call_arg = spy_send_event.call_args[0][0]
assert isinstance(call_arg, Analytics_ChangedLanguageEvent)