diff --git a/api/funkwhale_api/common/preferences.py b/api/funkwhale_api/common/preferences.py index e6eb8bedaaa140a6fc496258d839a242e7e9e213..a2d3f04b7f2414aa1e9602330c65b1abe3a9a750 100644 --- a/api/funkwhale_api/common/preferences.py +++ b/api/funkwhale_api/common/preferences.py @@ -1,4 +1,8 @@ from django.conf import settings +from django import forms + +from dynamic_preferences import serializers +from dynamic_preferences import types from dynamic_preferences.registries import global_preferences_registry @@ -10,3 +14,38 @@ class DefaultFromSettingMixin(object): def get(pref): manager = global_preferences_registry.manager() return manager[pref] + + +class StringListSerializer(serializers.BaseSerializer): + separator = ',' + sort = True + + @classmethod + def to_db(cls, value, **kwargs): + if not value: + return + + if type(value) not in [list, tuple]: + raise cls.exception( + "Cannot serialize, value {} is not a list or a tuple".format( + value)) + + if cls.sort: + value = sorted(value) + return cls.separator.join(value) + + @classmethod + def to_python(cls, value, **kwargs): + if not value: + return [] + return value.split(',') + + +class StringListPreference(types.BasePreferenceType): + serializer = StringListSerializer + field_class = forms.MultipleChoiceField + + def get_api_additional_data(self): + d = super(StringListPreference, self).get_api_additional_data() + d['choices'] = self.get('choices') + return d diff --git a/api/tests/common/test_preferences.py b/api/tests/common/test_preferences.py new file mode 100644 index 0000000000000000000000000000000000000000..475610a937c6c007dca06dda7045e2d41b61f6d9 --- /dev/null +++ b/api/tests/common/test_preferences.py @@ -0,0 +1,44 @@ +import pytest + +from dynamic_preferences.registries import global_preferences_registry +from funkwhale_api.common import preferences as common_preferences + + +@pytest.fixture +def string_list_pref(preferences): + + @global_preferences_registry.register + class P(common_preferences.StringListPreference): + default = ['hello'] + section = 'test' + name = 'string_list' + yield + del global_preferences_registry['test']['string_list'] + + +@pytest.mark.parametrize('input,output', [ + (['a', 'b', 'c'], 'a,b,c'), + (['a', 'c', 'b'], 'a,b,c'), + (('a', 'c', 'b'), 'a,b,c'), + ([], None), +]) +def test_string_list_serializer_to_db(input, output): + s = common_preferences.StringListSerializer.to_db(input) == output + + +@pytest.mark.parametrize('input,output', [ + ('a,b,c', ['a', 'b', 'c'], ), + (None, []), + ('', []), +]) +def test_string_list_serializer_to_python(input, output): + s = common_preferences.StringListSerializer.to_python(input) == output + + +def test_string_list_pref_default(string_list_pref, preferences): + assert preferences['test__string_list'] == ['hello'] + + +def test_string_list_pref_set(string_list_pref, preferences): + preferences['test__string_list'] = ['world', 'hello'] + assert preferences['test__string_list'] == ['hello', 'world']