diff --git a/CHANGELOG.md b/CHANGELOG.md index f32ca33c..9b20e84c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - executed commands are not displayed on the system default language and encoding (requires Flatpak >= 1.12) [#242](https://github.com/vinifmor/bauh/issues/242) - applications and runtimes descriptions are not displayed on the system default language (when available) [#242](https://github.com/vinifmor/bauh/issues/242) +- Web + - using the wrong locale format for the Accept-Language header + - UI: - fix: rare crash when updating table items diff --git a/bauh/gems/web/controller.py b/bauh/gems/web/controller.py index 615359a6..629b9916 100644 --- a/bauh/gems/web/controller.py +++ b/bauh/gems/web/controller.py @@ -59,6 +59,8 @@ RE_PROTOCOL_STRIP = re.compile(r'[a-zA-Z]+://') RE_SEVERAL_SPACES = re.compile(r'\s+') RE_SYMBOLS_SPLIT = re.compile(r'[\-|_\s:.]') +DEFAULT_LANGUAGE_HEADER = 'en-US, en' + class WebApplicationManager(SoftwareManager): @@ -77,12 +79,28 @@ class WebApplicationManager(SoftwareManager): self.idxman = SearchIndexManager(logger=context.logger) self._custom_actions: Optional[Iterable[CustomSoftwareAction]] = None - def _get_lang_header(self) -> str: + def get_accept_language_header(self) -> str: try: - system_locale = locale.getdefaultlocale() - return system_locale[0] if system_locale else 'en_US' + syslocale = locale.getdefaultlocale() + + if syslocale: + locale_split = syslocale[0].split('_') + + if len(locale_split) == 2: + sys_lang = f'{locale_split[0]}-{locale_split[1]}, {locale_split[0]}' + + if DEFAULT_LANGUAGE_HEADER.split(',')[1].strip() not in sys_lang: + return f'{sys_lang}, {DEFAULT_LANGUAGE_HEADER}' + + return sys_lang + + else: + return f'{syslocale[0]}, {DEFAULT_LANGUAGE_HEADER}' + else: + return DEFAULT_LANGUAGE_HEADER + except: - return 'en_US' + return DEFAULT_LANGUAGE_HEADER def clean_environment(self, root_password: Optional[str], watcher: ProcessWatcher) -> bool: handler = ProcessHandler(watcher) @@ -221,7 +239,7 @@ class WebApplicationManager(SoftwareManager): super(WebApplicationManager, self).serialize_to_disk(pkg=pkg, icon_bytes=None, only_icon=False) def _request_url(self, url: str) -> Optional[Response]: - headers = {'Accept-language': self._get_lang_header(), 'User-Agent': UA_CHROME} + headers = {'Accept-language': self.get_accept_language_header(), 'User-Agent': UA_CHROME} try: return self.http_client.get(url, headers=headers, ignore_ssl=True, single_call=True, session=False, allow_redirects=True) diff --git a/tests/gems/web/__init__.py b/tests/gems/web/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/gems/web/test_controller.py b/tests/gems/web/test_controller.py new file mode 100644 index 00000000..442ffe24 --- /dev/null +++ b/tests/gems/web/test_controller.py @@ -0,0 +1,47 @@ +from unittest import TestCase +from unittest.mock import Mock, patch + +from bauh.gems.web.controller import DEFAULT_LANGUAGE_HEADER +from bauh.gems.web.controller import WebApplicationManager + + +class ControllerTest(TestCase): + + def test_DEFAULT_LANGUAGE_HEADER(self): + self.assertEqual('en-US, en', DEFAULT_LANGUAGE_HEADER) + + +class WebApplicationManagerTest(TestCase): + + def setUp(self): + self.manager = WebApplicationManager(context=Mock()) + + @patch('locale.getdefaultlocale', side_effect=Exception) + def test_get_accept_language_header__must_return_default_locale_when_exception_raised(self, getdefaultlocale: Mock): + returned = self.manager.get_accept_language_header() + self.assertEqual(DEFAULT_LANGUAGE_HEADER, returned) + getdefaultlocale.assert_called_once() + + @patch('locale.getdefaultlocale', return_value=None) + def test_get_accept_language_header__must_return_default_locale_when_no_locale_is_returned(self, getdefaultlocale: Mock): + returned = self.manager.get_accept_language_header() + self.assertEqual(DEFAULT_LANGUAGE_HEADER, returned) + getdefaultlocale.assert_called_once() + + @patch('locale.getdefaultlocale', return_value=['es_AR']) + def test_get_accept_language_header__must_return_the_system_locale_without_underscore_plus_default_locale(self, getdefaultlocale: Mock): + returned = self.manager.get_accept_language_header() + self.assertEqual(f'es-AR, es, {DEFAULT_LANGUAGE_HEADER}', returned) + getdefaultlocale.assert_called_once() + + @patch('locale.getdefaultlocale', return_value=['es']) + def test_get_accept_language_header__must_return_the_simple_system_locale_plus_default_locale(self, getdefaultlocale: Mock): + returned = self.manager.get_accept_language_header() + self.assertEqual(f'es, {DEFAULT_LANGUAGE_HEADER}', returned) + getdefaultlocale.assert_called_once() + + @patch('locale.getdefaultlocale', return_value=['en_IN']) + def test_get_accept_language_header__must_not_concatenate_default_locale_if_system_locale_has_it(self, getdefaultlocale: Mock): + returned = self.manager.get_accept_language_header() + self.assertEqual(f'en-IN, en', returned) + getdefaultlocale.assert_called_once()