diff --git a/horizon/test/tests/utils.py b/horizon/test/tests/utils.py index ef8500e4dc..7b255669ed 100644 --- a/horizon/test/tests/utils.py +++ b/horizon/test/tests/utils.py @@ -444,47 +444,87 @@ class MemoizedTests(test.TestCase): self.assertIs(output1, output2) -class GetPageSizeTests(test.TestCase): +class GetConfigValueTests(test.TestCase): + key = 'key' + value = 'value' + requested_url = '/project/instances/' + int_default = 30 + str_default = 'default' + def test_bad_session_value(self): - requested_url = '/project/instances/' - request = self.factory.get(requested_url) - request.session['horizon_pagesize'] = 'not int-able' - default = 30 - self.assertEqual(functions.get_page_size(request, default), default) + request = self.factory.get(self.requested_url) + request.session[self.key] = self.value + res = functions.get_config_value(request, self.key, self.int_default) + self.assertEqual(res, self.int_default) def test_bad_cookie_value(self): - requested_url = '/project/instances/' - request = self.factory.get(requested_url) - if 'horizon_pagesize' in request.session: - del request.session['horizon_pagesize'] - request.COOKIES['horizon_pagesize'] = 'not int-able' - default = 30 - self.assertEqual(functions.get_page_size(request, default), default) + request = self.factory.get(self.requested_url) + if self.key in request.session: + del request.session[self.key] + request.COOKIES[self.key] = self.value + res = functions.get_config_value(request, self.key, self.int_default) + self.assertEqual(res, self.int_default) def test_float_default_value(self): - requested_url = '/project/instances/' - request = self.factory.get(requested_url) - request.session['horizon_pagesize'] = 'not int-able' default = 30.1 - expected = 30 - self.assertEqual(functions.get_page_size(request, default), expected) + request = self.factory.get(self.requested_url) + request.session[self.key] = self.value + res = functions.get_config_value(request, self.key, default) + self.assertEqual(res, self.value) def test_session_gets_set(self): - requested_url = '/project/instances/' - request = self.factory.get(requested_url) - request.session['horizon_pagesize'] = 'not int-able' - default = 30 - functions.get_page_size(request, default) - self.assertEqual(request.session['horizon_pagesize'], default) + request = self.factory.get(self.requested_url) + request.session[self.key] = self.value + functions.get_config_value(request, self.key, self.int_default) + self.assertEqual(request.session[self.key], self.int_default) - def test_bad_default_value(self): - requested_url = '/project/instances/' - request = self.factory.get(requested_url) - request.session['horizon_pagesize'] = 'not int-able' - default = 'also not int-able' - self.assertRaises(ValueError, - functions.get_page_size, - request, default) + def test_found_in_session(self): + request = self.factory.get(self.requested_url) + request.session[self.key] = self.value + if request.COOKIES.get(self.key): + del request.COOKIES[self.key] + res = functions.get_config_value(request, self.key, self.str_default) + self.assertEqual(res, self.value) + + def test_found_in_cookie(self): + request = self.factory.get(self.requested_url) + if request.session.get(self.key): + del request.session[self.key] + request.COOKIES[self.key] = self.value + res = functions.get_config_value(request, self.key, self.str_default) + self.assertEqual(res, self.value) + + def test_found_in_config(self): + key = 'TESTSERVER' + value = 'http://testserver' + request = self.factory.get(self.requested_url) + if request.session.get(key): + del request.session[key] + if request.COOKIES.get(key): + del request.COOKIES[key] + res = functions.get_config_value(request, key, self.str_default) + self.assertEqual(res, value) + + def test_return_default(self): + key = 'NOT FOUND ANYWHERE' + request = self.factory.get(self.requested_url) + if request.session.get(key): + del request.session[key] + if request.COOKIES.get(key): + del request.COOKIES[key] + res = functions.get_config_value(request, key, self.str_default) + self.assertEqual(res, self.str_default) + + def test_return_default_no_settings(self): + key = 'TESTSERVER' + request = self.factory.get(self.requested_url) + if request.session.get(key): + del request.session[key] + if request.COOKIES.get(key): + del request.COOKIES[key] + res = functions.get_config_value(request, key, self.str_default, + search_in_settings=False) + self.assertEqual(res, self.str_default) class UnitsTests(test.TestCase): diff --git a/horizon/utils/functions.py b/horizon/utils/functions.py index 4c19fb7646..8b93fb95e1 100644 --- a/horizon/utils/functions.py +++ b/horizon/utils/functions.py @@ -10,6 +10,7 @@ # License for the specific language governing permissions and limitations # under the License. +import datetime import decimal import math import re @@ -64,33 +65,54 @@ def logout_with_message(request, msg, redirect=True): return response -def get_page_size(request, default=20): - session = request.session - cookies = request.COOKIES - try: - page_size = int(session.get('horizon_pagesize', - cookies.get('horizon_pagesize', - getattr(settings, - 'API_RESULT_PAGE_SIZE', - default)))) - except ValueError: - page_size = session['horizon_pagesize'] = int(default) - return page_size +def get_config_value(request, key, default, search_in_settings=True): + """Retrieves the value of `key` from configuration in the following order: + - from the session; if not found there then + - from cookies; if not found there then + - from the settings file if `search_in_settings` is True, + otherwise this step is skipped; if not found there + - `default` is returned + """ + value = request.session.get(key, request.COOKIES.get(key)) + + if value is None: + if search_in_settings: + value = getattr(settings, key, default) + else: + value = default + + if isinstance(default, int): + try: + value = int(value) + except ValueError: + value = request.session[key] = int(default) + + return value -def get_log_length(request, default=35): - session = request.session - cookies = request.COOKIES - try: - log_length = int(session.get( - 'instance_log_length', - cookies.get('instance_log_length', - getattr(settings, - 'INSTANCE_LOG_LENGTH', - default)))) - except ValueError: - log_length = session['instance_log_length'] = int(default) - return log_length +def save_config_value(request, response, key, value): + """Sets value of key `key` to `value` in both session and cookies. + """ + request.session[key] = value + response.set_cookie(key, value, expires=one_year_from_now()) + return response + + +def get_page_size(request): + return get_config_value(request, 'API_RESULT_PAGE_SIZE', 20) + + +def get_log_length(request): + return get_config_value(request, 'INSTANCE_LOG_LENGTH', 35) + + +def get_timezone(request): + return get_config_value(request, 'django_timezone', 'UTC') + + +def get_language(request): + return get_config_value(request, settings.LANGUAGE_COOKIE_NAME, + request.LANGUAGE_CODE, search_in_settings=False) def natural_sort(attr): @@ -147,5 +169,11 @@ def format_value(value): value = decimal.Decimal(str(value)) if int(value) == value: return int(value) + # On Python 3, an explicit cast to float is required return float(round(value, 1)) + + +def one_year_from_now(): + now = datetime.datetime.utcnow() + return now + datetime.timedelta(days=365) diff --git a/openstack_dashboard/dashboards/settings/user/forms.py b/openstack_dashboard/dashboards/settings/user/forms.py index e704239645..9119cefbe5 100644 --- a/openstack_dashboard/dashboards/settings/user/forms.py +++ b/openstack_dashboard/dashboards/settings/user/forms.py @@ -27,11 +27,7 @@ import pytz from horizon import forms from horizon import messages - - -def _one_year(): - now = datetime.utcnow() - return now + timedelta(days=365) +from horizon.utils import functions class UserSettingsForm(forms.SelfHandlingForm): @@ -106,27 +102,22 @@ class UserSettingsForm(forms.SelfHandlingForm): def handle(self, request, data): response = shortcuts.redirect(request.build_absolute_uri()) - # Language + lang_code = data['language'] if lang_code and translation.check_for_language(lang_code): - if hasattr(request, 'session'): - request.session['django_language'] = lang_code - response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code, - expires=_one_year()) + response = functions.save_config_value( + request, response, settings.LANGUAGE_COOKIE_NAME, lang_code) - # Timezone - request.session['django_timezone'] = pytz.timezone( - data['timezone']).zone - response.set_cookie('django_timezone', data['timezone'], - expires=_one_year()) + response = functions.save_config_value( + request, response, 'django_timezone', + pytz.timezone(data['timezone']).zone) - request.session['horizon_pagesize'] = data['pagesize'] - response.set_cookie('horizon_pagesize', data['pagesize'], - expires=_one_year()) + response = functions.save_config_value( + request, response, 'API_RESULT_PAGE_SIZE', data['pagesize']) - request.session['instance_log_length'] = data['instance_log_length'] - response.set_cookie('instance_log_length', - data['instance_log_length'], expires=_one_year()) + response = functions.save_config_value( + request, response, 'INSTANCE_LOG_LENGTH', + data['instance_log_length']) with translation.override(lang_code): messages.success(request, diff --git a/openstack_dashboard/dashboards/settings/user/views.py b/openstack_dashboard/dashboards/settings/user/views.py index 66f70253a5..e5a4aecbed 100644 --- a/openstack_dashboard/dashboards/settings/user/views.py +++ b/openstack_dashboard/dashboards/settings/user/views.py @@ -12,7 +12,6 @@ # License for the specific language governing permissions and limitations # under the License. -from django.conf import settings from django.core.urlresolvers import reverse_lazy from django.utils.translation import ugettext_lazy as _ @@ -31,15 +30,9 @@ class UserSettingsView(forms.ModalFormView): template_name = 'settings/user/settings.html' def get_initial(self): - default_tz = getattr(settings, 'TIME_ZONE', 'UTC') return { - 'language': self.request.session.get( - settings.LANGUAGE_COOKIE_NAME, - self.request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME, - self.request.LANGUAGE_CODE)), - 'timezone': self.request.session.get( - 'django_timezone', - self.request.COOKIES.get('django_timezone', default_tz)), + 'language': utils.get_language(self.request), + 'timezone': utils.get_timezone(self.request), 'pagesize': utils.get_page_size(self.request), 'instance_log_length': utils.get_log_length(self.request)}