From bea62d75a9b8d3b3300299c56cafda71534d252e Mon Sep 17 00:00:00 2001 From: 3252a8 <3252a8@proton.me> Date: Thu, 28 May 2026 22:07:43 +0300 Subject: [PATCH] fix: persist account language changes --- backend/bot/app/web/webapp/account.py | 1 + tests/test_webapp_account_language.py | 72 +++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 tests/test_webapp_account_language.py diff --git a/backend/bot/app/web/webapp/account.py b/backend/bot/app/web/webapp/account.py index f090f4c..cd7cd46 100644 --- a/backend/bot/app/web/webapp/account.py +++ b/backend/bot/app/web/webapp/account.py @@ -482,6 +482,7 @@ async def account_avatar_route(request: web.Request) -> web.Response: async def account_language_route(request: web.Request) -> web.Response: user_id = _require_user_id(request) + settings: Settings = request.app["settings"] payload = await _read_json(request) language_payload, validation_error = _validate_model_payload(WebAppLanguagePayload, payload) if validation_error: diff --git a/tests/test_webapp_account_language.py b/tests/test_webapp_account_language.py new file mode 100644 index 0000000..0c5cb8e --- /dev/null +++ b/tests/test_webapp_account_language.py @@ -0,0 +1,72 @@ +import json +from types import SimpleNamespace +from unittest import IsolatedAsyncioTestCase +from unittest.mock import AsyncMock, Mock, patch + +import bot.app.web.subscription_webapp # noqa: F401 +from bot.app.web.webapp import account as account_module + + +class _JsonRequest(SimpleNamespace): + async def json(self): + return self.payload + + +class _SessionFactory: + def __init__(self, session): + self.session = session + + def __call__(self): + return self + + async def __aenter__(self): + return self.session + + async def __aexit__(self, exc_type, exc, tb): + return False + + +class WebAppAccountLanguageTests(IsolatedAsyncioTestCase): + async def test_account_language_route_updates_language_and_invalidates_cache(self): + settings = SimpleNamespace() + session = SimpleNamespace( + flush=AsyncMock(), + commit=AsyncMock(), + rollback=AsyncMock(), + ) + user = SimpleNamespace(user_id=42, language_code="ru", is_banned=False) + i18n = SimpleNamespace( + locales_data={"ru": {}, "en": {}}, + reload_overrides_from_file=Mock(), + ) + request = _JsonRequest( + app={ + "settings": settings, + "async_session_factory": _SessionFactory(session), + "i18n": i18n, + }, + payload={"language": "en"}, + ) + + with ( + patch.object(account_module, "_require_user_id", return_value=42), + patch.object( + account_module.user_dal, + "get_user_by_id", + AsyncMock(return_value=user), + ), + patch.object( + account_module, + "_invalidate_webapp_user_caches", + AsyncMock(), + ) as invalidate_cache, + ): + response = await account_module.account_language_route(request) + + self.assertEqual(response.status, 200) + self.assertEqual(json.loads(response.text), {"ok": True, "language": "en"}) + self.assertEqual(user.language_code, "en") + i18n.reload_overrides_from_file.assert_called_once_with() + session.flush.assert_awaited_once() + session.commit.assert_awaited_once() + invalidate_cache.assert_awaited_once_with(settings, 42)